✨ Fake filesystem in `BBSFakeUserEnv` now loaded from a JSON file
authorMalte Bublitz <malte@rolltreppe3.de>
Sat, 6 Dec 2025 17:19:09 +0000 (18:19 +0100)
committerMalte Bublitz <malte@rolltreppe3.de>
Sat, 6 Dec 2025 17:19:09 +0000 (18:19 +0100)
- The default fake filesystem moved to a data direcotry in the Python
  package `bbs`
- An alternative data file can be passed to `bbs.env.BBSFakeUserEnv`
  (although not used by `bbs.minishell` yes)

bbs/data/bbs_fs.json [new file with mode: 0644]
bbs/env.py

diff --git a/bbs/data/bbs_fs.json b/bbs/data/bbs_fs.json
new file mode 100644 (file)
index 0000000..08b92e8
--- /dev/null
@@ -0,0 +1,10 @@
+{
+       "A:": {
+               "BOFH.TXT": "Easter Egg:\n\nRun `bofh` or `sry` to get an random BOFH excuse",
+               "DOCTOR.TXT": "Easter Egg 2:\n\nTry logging in as `doctor` or `doctorwho`, and run `hostname`..."
+       },
+       "C:": {
+               "HELLO.TXT": "Hello World!",
+               "ROLLTREPPE3.URL": "https://rolltreppe3.de"
+       }
+}
index d21c8aec2d1dee3d7f24f68a8c0a6576b4b49af9..de983bc2b2a7bc13543bdcb0fa6856aab4ee0cbb 100644 (file)
@@ -1,83 +1,99 @@
-# -*- coding: utf-8 -*-
+__doc__ == """Fake environment for the BBS.
 
+The class BBSFakeUserEnv provides the fake environment for bbs.minishell,
+including the “file system” (loaded from a JSON file).
+"""
+
+
+import json
+import os
 import platform
 
-class BBSFakeUserEnv(object):
-    _user = ""
-    _node = ""
-    _name = ""
-    _hideRealUname = False
-    _runningInsideLXC = False
-    _pwd = "C:"
-    _fileSystem = {
-        "A:": {
-            "BOFH.TXT": "Easter Egg:\n\nRun `bofh` or `sry` to get an random BOFH excuse",
-            "DOCTOR.TXT": "Easter Egg 2:\n\nTry logging in as `doctor` or `doctorwho`, and run `hostname`...",
-        },
-        "C:": {
-            "HELLO.TXT":       "Hello World!",
-            "ROLLTREPPE3.URL": "https://rolltreppe3.de",
-        },
-    }
-    
-    def setUser(self, _user):
-        self._user = _user
-        
-    def getUser(self):
-        return self._user
-        
-    def setNode(self, _node):
-        self._node = _node
-        
-    def getNode(self):
-        return self._node
-        
-    def getName(self):
-        return self._name
-        
-    def setHideRealUname(self, _hideRealUname):
-        self._hideRealUname = _hideRealUname
-
-    def setRunningInsideLXC(self, _isInsideLXC):
-        self._runningInsideLXC = _isInsideLXC
-
-    def getRunningInsideLXC(self):
-        return self._runningInsideLXC
-
-    def getHome(self):
-        #return "/usr/home/" + self.getUser()
-        _user = self.getUser().upper()
-        if len(_user) > 10:
-            _user = _user[:8] + "~1"
-        return "C:\\DATA\\" + _user + "\\"
-        
-    def getCurrentDir(self, realPwd = False):
-        if not realPwd and self._pwd == "C:":
-            return self.getHome()
-        else:
-            return self._pwd + "\\"
-
-    def setCurrentDir(self, new_pwd):
-        self._pwd = new_pwd
-
-    def getDirListing(self):
-        return self._fileSystem[self._pwd].keys()
-        
-    def getFileContents(self, filename):
-        return self._fileSystem[self._pwd][filename]
-
-    def getPrompt(self, ps1="%w>"):
-        return ps1.replace("%w", self.getCurrentDir(True))
-
-    def getUName(self):
-        if not self._hideRealUname:
-            return platform.uname()[0]+" "+platform.uname()[1]+" "+platform.uname()[2]
-        else:
-            return "BBS-UX "+self.getNode()+" r42"
-        
-    def __init__(self):
-        self._user = "doctor_who"
-        self._node = platform.node()
-        #self._node = platform.uname()[1]
-        self._name = "I am the Doctor!"
-        
+
+class BBSFakeUserEnv:
+       _user = ""
+       _node = ""
+       _name = ""
+       _hideRealUname = False
+       _runningInsideLXC = False
+       _pwd = "C:"
+       _fileSystem = {}
+
+       def setUser(self, _user):
+               self._user = _user
+
+       def getUser(self):
+               return self._user
+
+       def setNode(self, _node):
+               self._node = _node
+
+       def getNode(self):
+               return self._node
+
+       def getName(self):
+               return self._name
+
+       def setHideRealUname(self, _hideRealUname):
+               self._hideRealUname = _hideRealUname
+
+       def setRunningInsideLXC(self, _isInsideLXC):
+               self._runningInsideLXC = _isInsideLXC
+
+       def getRunningInsideLXC(self):
+               return self._runningInsideLXC
+
+       def getHome(self):
+               #return "/usr/home/" + self.getUser()
+               _user = self.getUser().upper()
+               if len(_user) > 10:
+                       _user = _user[:8] + "~1"
+               return "C:\\DATA\\" + _user + "\\"
+
+       def getCurrentDir(self, realPwd = True):
+               if not realPwd and self._pwd == "C:":
+                       return self.getHome()
+               else:
+                       return self._pwd + "\\"
+
+       def setCurrentDir(self, new_pwd: str):
+               new_pwd = new_pwd.upper()
+               if not new_pwd in self._fileSystem.keys():
+                       raise FileNotFoundError(f"No such drive: \'{new_pwd}\'")
+               self._pwd = new_pwd
+
+       def getDirListing(self):
+               return self._fileSystem[self._pwd].keys()
+
+       def getFileContents(self, filename: str):
+               filename = filename.upper()
+               if not filename in self._fileSystem[self._pwd].keys():
+                       raise FileNotFoundError(f"No such file: \'{filename}\'")
+               return self._fileSystem[self._pwd][filename]
+
+       def getPrompt(self, ps1="%w>"):
+               return ps1.replace("%w", self.getCurrentDir(True))
+
+       def getUName(self):
+               if not self._hideRealUname:
+                       return platform.uname()[0]+" "+platform.uname()[1]+" "+platform.uname()[2]
+               else:
+                       return "BBS-UX "+self.getNode()+" r42"
+
+       def __init__(self, filesystem_data_file: str = None):
+               self._user = "doctor_who"
+               self._node = platform.node()
+               #self._node = platform.uname()[1]
+               self._name = "I am the Doctor!"
+
+               if filesystem_data_file is None:
+                       filesystem_data_file = os.path.join(
+                               os.path.dirname(__file__),
+                               "data",
+                               "bbs_fs.json"
+                       )
+
+               with open(filesystem_data_file, "r") as f:
+                       self._fileSystem = json.load(f)
+
+