# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-import argparse, sys, os, re, subprocess
+import argparse, sys, os, os.path, shutil, re, subprocess
from enum import Enum
-import gui, screen
+import gui, screen, util, database
frontend = gui.getFrontend("cli") # the fallback, until we got a proper frontend. This is guaranteed to be available.
for suffix in commonInternalConnectorSuffices:
yield prefix+suffix
-
# Load a section-less config file: maps parameter names to space-separated lists of strings (with shell quotation)
def loadConfigFile(filename):
import shlex
# run!
return screen.ScreenSituation(internalConnectors, config.get('externalConnectors'))
+class ShowLevels(Enum):
+ ONEXTERNAL = ("on-external")
+ ONNEW = ("on-new")
+ ONERROR = ("on-error")
+ def __init__(self, text):
+ # auto numbering
+ cls = self.__class__
+ self._value_ = len(cls.__members__) + 1
+ self.text = text
+ @classmethod
+ def getNames(cls):
+ return list(x.text for x in cls)
# if we run top-level
if __name__ == "__main__":
parser.add_argument("-i", "--internal-only",
dest="internal_only", action='store_true',
help="Enable internal screen, disable all the others.")
+ parser.add_argument("-s", "--show",
+ dest="show", choices=ShowLevels.getNames(), default=ShowLevels.ONEXTERNAL.text,
+ help="In which situations should the UI be displayed?")
cmdArgs = parser.parse_args()
# load frontend early (for error mssages)
frontend = gui.getFrontend(cmdArgs.frontend)
+ # find files
+ ## find config file
+ legacyConfigFilePath = os.getenv('HOME') + '/.lilass.conf'
+ configDirectory = util.getConfigDirectory()
+ configFilePath = os.path.join(configDirectory, "lilass.conf")
+ if os.path.isfile(legacyConfigFilePath) and not os.path.isfile(configFilePath):
+ # looks like we just upgraded to a new version of lilass
+ util.mkdirP(configDirectory)
+ shutil.move(legacyConfigFilePath, configFilePath)
+ ## find database
+ dataDirectory = util.getDataDirectory()
+ util.mkdirP(dataDirectory)
+ databaseFilePath = os.path.join(dataDirectory, "collected_data.sqlite")
+
# load configuration
- config = loadConfigFile(os.getenv('HOME') + '/.lilass.conf')
+ config = loadConfigFile(configFilePath)
# see what situation we are in
situation = situationByConfig(config)
+ # fetch info from the database
+ # if it is too slow to open the DB twice (reading and saving), we can keep it open all the time
+ with database.Database(databaseFilePath) as db:
+ situation.fetchDBInfo(db)
+
# construct the ScreenSetup
setup = None
if not cmdArgs.internal_only and situation.externalResolutions() is not None:
else:
setup = screen.ScreenSetup(intResolution = situation.internalResolutions()[0], extResolution = situation.externalResolutions()[0], relPosition = relPos)
else:
- # ask the user
- setup = frontend.setup(situation)
- if setup is None: sys.exit(1) # the user canceled
+ showlvl = ShowLevels(cmdArgs.show)
+ if showlvl != ShowLevels.ONEXTERNAL and situation.lastSetup:
+ # use last config
+ setup = situation.lastSetup
+ elif showlvl == ShowLevels.ONERROR:
+ # guess config
+ setup = screen.ScreenSetup(situation.internalResolutions()[0], situation.externalResolutions()[0], screen.RelativeScreenPosition.RIGHT)
+ # TODO make default relative position configurable in the config file
+ # TODO this has a bit of code duplication with the cmdArgs method above
+ else:
+ # ask the user
+ setup = frontend.setup(situation)
+ if setup is None: sys.exit(1) # the user canceled
+ with database.Database(databaseFilePath) as db:
+ situation.putDBInfo(db, setup)
else:
# use first resolution of internal connector
- setup = screen.ScreenSetup(intResolution = situation.internalResolutions()[0], extResolution = None)
+ setup = screen.ScreenSetup(intResolution = situation.internalConnector.getResolutionList()[0], extResolution = None)
# call xrandr
xrandrCall = situation.forXrandr(setup)
if setup.extResolution is None:
turnOnBacklight()
except Exception as e:
+ raise e
frontend.error(str(e))