+# Copyright (c) 2005 mudpy, Jeremy Stanley <fungi@yuggoth.org>, all rights reserved.
+# Licensed per terms in the LICENSE file distributed with this software.
+
+# persistent variables are stored in ini-style files supported by ConfigParser
+import ConfigParser
+
+# need to know the directory separator
+import os
+
+# hack to load all modules in the muff package
+import muff
+for module in muff.__all__:
+ exec("import " + module)
+
+class Element:
+ """An element of the universe."""
+ def __init__(self, key, universe, origin=""):
+ """Default values for the in-memory element variables."""
+ self.key = key
+ if self.key.find(":") > 0:
+ self.category, self.subkey = self.key.split(":", 1)
+ else:
+ self.category = "other"
+ self.subkey = self.key
+ if not self.category in universe.categories: self.category = "other"
+ universe.categories[self.category][self.subkey] = self
+ self.origin = origin
+ if not self.origin: self.origin = universe.default_origins[self.category]
+ if not self.origin.startswith(os.sep):
+ self.origin = os.getcwd() + os.sep + self.origin
+ universe.contents[self.key] = self
+ if not self.origin in universe.files:
+ DataFile(self.origin, universe)
+ if not universe.files[self.origin].data.has_section(self.key):
+ universe.files[self.origin].data.add_section(self.key)
+ def delete(self):
+ muffmisc.log("Deleting: " + self.key + ".")
+ universe.files[self.origin].data.remove_section(self.key)
+ del universe.categories[self.category][self.subkey]
+ del universe.contents[self.key]
+ del self
+ def facets(self):
+ """Return a list of facets for this element."""
+ return universe.files[self.origin].data.options(self.key)
+ def get(self, facet):
+ """Retrieve values."""
+ if universe.files[self.origin].data.has_option(self.key, facet):
+ return universe.files[self.origin].data.get(self.key, facet)
+ else:
+ return ""
+ def getboolean(self, facet, default=False):
+ """Retrieve values as boolean type."""
+ if universe.files[self.origin].data.has_option(self.key, facet):
+ return universe.files[self.origin].data.getboolean(self.key, facet)
+ else:
+ return default
+ def getint(self, facet):
+ """Convenience method to coerce return values as type int."""
+ value = self.get(facet)
+ if not value: value = 0
+ elif type(value) is str: value = value.rstrip("L")
+ return int(value)
+ def getfloat(self, facet):
+ """Convenience method to coerce return values as type float."""
+ value = self.get(facet)
+ if not value: value = 0
+ elif type(value) is str: value = value.rstrip("L")
+ return float(value)
+ def set(self, facet, value):
+ """Set values."""
+ if not type(value) is str: value = repr(value)
+ universe.files[self.origin].data.set(self.key, facet, value)
+
+class DataFile:
+ """A file containing universe elements."""
+ def __init__(self, filename, universe):
+ filedir = os.sep.join(filename.split(os.sep)[:-1])
+ self.data = ConfigParser.SafeConfigParser()
+ if os.access(filename, os.R_OK): self.data.read(filename)
+ self.filename = filename
+ universe.files[filename] = self
+ if "categories" in self.data.sections():
+ for option in self.data.options("categories"):
+ universe.default_origins[option] = self.data.get("categories", option)
+ if not option in universe.categories:
+ universe.categories[option] = {}
+ for section in self.data.sections():
+ if section == "categories" or section == "include":
+ for option in self.data.options(section):
+ includefile = self.data.get(section, option)
+ if not includefile.startswith(os.sep):
+ includefile = filedir + os.sep + includefile
+ DataFile(includefile, universe)
+ elif section != "control":
+ Element(section, universe, filename)
+ def save(self):
+ if self.data.sections() and not ( "control" in self.data.sections() and self.data.getboolean("control", "read_only") ):
+ basedir = os.sep.join(self.filename.split(os.sep)[:-1])
+ if not os.access(basedir, os.F_OK): os.makedirs(basedir)
+ file_descriptor = file(self.filename, "w")
+ self.data.write(file_descriptor)
+ file_descriptor.flush()
+ file_descriptor.close()
+
+class Universe:
+ """The universe."""
+ def __init__(self, filename=""):
+ """Initialize the universe."""
+ self.categories = {}
+ self.contents = {}
+ self.default_origins = {}
+ self.files = {}
+ if not filename:
+ possible_filenames = [
+ ".mudpyrc",
+ ".mudpy/mudpyrc",
+ ".mudpy/mudpy.conf",
+ "mudpy.conf",
+ "etc/mudpy.conf",
+ "/usr/local/mudpy/mudpy.conf",
+ "/usr/local/mudpy/etc/mudpy.conf",
+ "/etc/mudpy/mudpy.conf",
+ "/etc/mudpy.conf"
+ ]
+ for filename in possible_filenames:
+ if os.access(filename, os.R_OK): break
+ if not filename.startswith(os.sep):
+ filename = os.getcwd() + os.sep + filename
+ DataFile(filename, self)
+ def save(self):
+ """Save the universe to persistent storage."""
+ for key in self.files: self.files[key].save()
+
+# if there is no universe, create an empty one
+if not "universe" in locals(): universe = Universe()
+