2019-11-27 01:34:01 +00:00
|
|
|
"""stores configuration settings for linkulator"""
|
2019-12-03 01:52:37 +00:00
|
|
|
import configparser
|
2019-11-30 12:00:37 +00:00
|
|
|
import stat
|
2019-11-27 01:34:01 +00:00
|
|
|
from pathlib import Path
|
2019-11-30 12:00:37 +00:00
|
|
|
from time import time
|
2019-11-27 01:34:01 +00:00
|
|
|
|
|
|
|
|
2019-11-30 12:00:37 +00:00
|
|
|
class DefaultPaths:
|
|
|
|
"""data class containing configurable path defaults"""
|
2019-11-27 01:34:01 +00:00
|
|
|
|
2019-11-30 12:00:37 +00:00
|
|
|
all_homedir_pattern: str = "/home/*/"
|
|
|
|
datadir: str = ".linkulator"
|
|
|
|
datafile: str = "linkulator.data"
|
|
|
|
ignorefile: str = "ignore"
|
|
|
|
settingsfile: str = "linkulatorrc"
|
2019-11-27 01:34:01 +00:00
|
|
|
|
|
|
|
|
2019-11-30 12:00:37 +00:00
|
|
|
PATHS = DefaultPaths()
|
2019-11-29 02:05:10 +00:00
|
|
|
|
2019-11-30 12:00:37 +00:00
|
|
|
|
2019-12-03 01:52:37 +00:00
|
|
|
class DefaultUser:
|
2019-11-30 12:00:37 +00:00
|
|
|
"""data class containing user defaults"""
|
|
|
|
|
|
|
|
datadir: Path = Path.home() / PATHS.datadir
|
|
|
|
datafile: Path = datadir / PATHS.datafile
|
|
|
|
ignorefile: Path = datadir / PATHS.ignorefile
|
|
|
|
settingsfile: Path = datadir / PATHS.settingsfile
|
|
|
|
lastlogin = time()
|
|
|
|
browser: str = "lynx"
|
|
|
|
|
2019-12-03 01:52:37 +00:00
|
|
|
def save(self):
|
|
|
|
"""Saves config data to file"""
|
|
|
|
config = configparser.ConfigParser()
|
|
|
|
config["User Status"] = {"lastlogin": self.lastlogin}
|
|
|
|
config["User Settings"] = {"browser": self.browser}
|
|
|
|
with open(self.settingsfile, "w") as file:
|
|
|
|
config.write(file)
|
|
|
|
|
|
|
|
def load(self):
|
|
|
|
"""Loads from config file"""
|
|
|
|
config = configparser.ConfigParser()
|
|
|
|
ret = config.read(self.settingsfile)
|
|
|
|
if len(ret) > 0:
|
|
|
|
self.lastlogin = config["User Status"]["lastlogin"]
|
|
|
|
self.browser = config["User Settings"]["browser"]
|
|
|
|
|
2019-11-30 12:00:37 +00:00
|
|
|
|
|
|
|
USER = DefaultUser()
|
|
|
|
|
|
|
|
|
|
|
|
def is_readable(st_mode: int) -> bool:
|
|
|
|
"""Checks the provided mode is group and other readable, returns true if this is the case
|
|
|
|
|
|
|
|
Check if 700 is readable:
|
|
|
|
>>> is_readable(16832)
|
|
|
|
False
|
|
|
|
|
|
|
|
Check if 755 is readable:
|
|
|
|
>>> is_readable(16877)
|
|
|
|
True
|
|
|
|
"""
|
|
|
|
if bool(st_mode & stat.S_IRGRP) & bool(st_mode & stat.S_IROTH):
|
|
|
|
return True
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
def init():
|
|
|
|
"""Performs startup checks to ensure environment is set up for use
|
|
|
|
|
|
|
|
Creates necessary data directory and data file. If they exist, no error
|
|
|
|
occurs.
|
|
|
|
Checks that the data directory and data file are group and other readable.
|
|
|
|
Sets some correct permissions if they are not.
|
|
|
|
Other errors may raise an exception.
|
|
|
|
"""
|
|
|
|
|
|
|
|
USER.datadir.mkdir(mode=0o755, exist_ok=True)
|
|
|
|
|
|
|
|
if not is_readable(USER.datadir.stat().st_mode):
|
|
|
|
print(
|
|
|
|
"Warning: %s is not group or other readable - changing permissions"
|
|
|
|
% str(USER.datadir)
|
|
|
|
)
|
|
|
|
USER.datadir.chmod(0o755)
|
|
|
|
|
|
|
|
USER.datafile.touch(mode=0o644, exist_ok=True)
|
|
|
|
|
|
|
|
if not is_readable(USER.datafile.stat().st_mode):
|
|
|
|
print(
|
|
|
|
"Warning: %s is not group or other readable - changing permissions"
|
|
|
|
% str(USER.datafile)
|
|
|
|
)
|
|
|
|
USER.datafile.chmod(0o644)
|
|
|
|
|
|
|
|
try:
|
2019-12-03 01:52:37 +00:00
|
|
|
USER.load()
|
|
|
|
except configparser.MissingSectionHeaderError:
|
|
|
|
print(
|
|
|
|
"Warning: config file has invalid syntax and will be overwritten with default values"
|
|
|
|
)
|