Skip to content

Commit 7def510

Browse files
authored
Merge pull request #27 from makermelissa/main
New features required for installer script changes
2 parents 9358afe + 01be1e4 commit 7def510

File tree

1 file changed

+110
-5
lines changed

1 file changed

+110
-5
lines changed

adafruit_shell.py

Lines changed: 110 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
# imports
2424
import sys
2525
import os
26+
import stat
2627
import shutil
2728
import subprocess
2829
import fcntl
@@ -50,10 +51,28 @@
5051

5152
WINDOW_MANAGERS = {
5253
"x11": "W1",
53-
"wayland": "W2",
54+
"wayfire": "W2",
5455
"labwc": "W3",
5556
}
5657

58+
FILE_MODES = {
59+
"+x": stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH,
60+
"+r": stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH,
61+
"+w": stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH,
62+
"a+x": stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH,
63+
"a+r": stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH,
64+
"a+w": stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH,
65+
"u+x": stat.S_IXUSR,
66+
"u+r": stat.S_IRUSR,
67+
"u+w": stat.S_IWUSR,
68+
"g+x": stat.S_IXGRP,
69+
"g+r": stat.S_IRGRP,
70+
"g+w": stat.S_IWGRP,
71+
"o+x": stat.S_IXOTH,
72+
"o+r": stat.S_IROTH,
73+
"o+w": stat.S_IWOTH,
74+
}
75+
5776

5877
# pylint: disable=too-many-public-methods
5978
class Shell:
@@ -142,6 +161,50 @@ def preexec():
142161
return False
143162
return True
144163

164+
def write_templated_file(self, output_path, template, **kwargs):
165+
"""
166+
Use a template file and render it with the given context and write it to the specified path.
167+
The template file should contain placeholders in the format {key} which will be replaced
168+
with the corresponding values from the kwargs dictionary.
169+
"""
170+
# if path is an existing directory, the template filename will be used
171+
output_path = self.path(output_path)
172+
if os.path.isdir(output_path):
173+
output_path = os.path.join(output_path, os.path.basename(template))
174+
175+
# Render the template with the provided context
176+
rendered_content = self.load_template(template, **kwargs)
177+
178+
if rendered_content is None:
179+
self.error(
180+
f"Failed to load template '{template}'. Unable to write file '{output_path}'."
181+
)
182+
return False
183+
184+
append = kwargs.get("append", False)
185+
self.write_text_file(output_path, rendered_content, append=append)
186+
187+
return True
188+
189+
def load_template(self, template, **kwargs):
190+
"""
191+
Load a template file and return its content with the placeholders replaced by the provided
192+
context. The template file should contain placeholders in the format {key} which will be
193+
replaced with the corresponding values from the kwargs dictionary.
194+
"""
195+
if not os.path.exists(template):
196+
self.error(f"Template file '{template}' does not exist")
197+
return None
198+
199+
with open(template, "r") as template_file:
200+
template_content = template_file.read()
201+
202+
# Render the template with the provided context
203+
for key, value in kwargs.items():
204+
template_content = template_content.replace(f"{{{key}}}", str(value))
205+
206+
return template_content
207+
145208
def info(self, message, **kwargs):
146209
"""
147210
Display a message with the group in green
@@ -321,7 +384,10 @@ def reconfig(self, file, pattern, replacement):
321384
# Not found; append (silently)
322385
self.write_text_file(file, replacement, append=True)
323386

324-
def pattern_search(self, location, pattern, multi_line=False, return_match=False):
387+
# pylint: disable=too-many-arguments
388+
def pattern_search(
389+
self, location, pattern, multi_line=False, return_match=False, find_all=False
390+
):
325391
"""
326392
Similar to grep, but uses pure python
327393
multi_line will search the entire file as a large text glob,
@@ -331,16 +397,17 @@ def pattern_search(self, location, pattern, multi_line=False, return_match=False
331397
"""
332398
location = self.path(location)
333399
found = False
400+
search_function = re.findall if find_all else re.search
334401

335402
if self.exists(location) and not self.isdir(location):
336403
if multi_line:
337404
with open(location, "r+", encoding="utf-8") as file:
338-
match = re.search(pattern, file.read(), flags=re.DOTALL)
405+
match = search_function(pattern, file.read(), flags=re.DOTALL)
339406
if match:
340407
found = True
341408
else:
342409
for line in fileinput.FileInput(location):
343-
match = re.search(pattern, line)
410+
match = search_function(pattern, line)
344411
if match:
345412
found = True
346413
break
@@ -417,8 +484,13 @@ def chmod(self, location, mode):
417484
Change the permissions of a file or directory
418485
"""
419486
location = self.path(location)
487+
# Convert a text mode to an integer mode
488+
if isinstance(mode, str):
489+
if mode not in FILE_MODES:
490+
raise ValueError(f"Invalid mode string '{mode}'")
491+
mode = FILE_MODES[mode]
420492
if not 0 <= mode <= 0o777:
421-
raise ValueError("Invalid mode value")
493+
raise ValueError(f"Invalid mode value '{mode}'")
422494
if os.path.exists(location):
423495
os.chmod(location, mode)
424496

@@ -475,6 +547,16 @@ def write_text_file(self, path, content, append=True):
475547
with open(self.path(path), mode, encoding="utf-8") as service_file:
476548
service_file.write(content)
477549

550+
def read_text_file(self, path):
551+
"""
552+
Read the contents of a file at the specified path
553+
"""
554+
path = self.path(path)
555+
if not os.path.exists(path):
556+
raise FileNotFoundError(f"File '{path}' does not exist")
557+
with open(path, "r", encoding="utf-8") as file:
558+
return file.read()
559+
478560
@staticmethod
479561
def is_python3():
480562
"Check if we are running Python 3 or later"
@@ -656,6 +738,29 @@ def set_window_manager(self, manager):
656738
):
657739
raise RuntimeError("Unable to change window manager")
658740

741+
def get_window_manager(self):
742+
"""
743+
Get the current window manager
744+
"""
745+
sessions = {"wayfire": "LXDE-pi-wayfire"}
746+
# Check for Raspbian Desktop sessions
747+
if self.exists("/usr/share/xsessions/rpd-x.desktop") or self.exists(
748+
"/usr/share/wayland-sessions/rpd-labwc.desktop"
749+
):
750+
sessions.update({"x11": "rpd-x", "labwc": "rpd-labwc"})
751+
else:
752+
sessions.update({"x11": "LXDE-pi-x", "labwc": "LXDE-pi-labwc"})
753+
754+
matches = self.pattern_search(
755+
"/etc/lightdm/lightdm.conf", "^(?!#.*?)user-session=(.+)", False, True
756+
)
757+
if matches:
758+
session_match = matches.group(1)
759+
for key, session in sessions.items():
760+
if session_match == session:
761+
return key
762+
return None
763+
659764
def get_boot_config(self):
660765
"""
661766
Get the location of the boot config file

0 commit comments

Comments
 (0)