Fix namespaces

This commit is contained in:
Tim Van Baak 2020-01-23 15:13:34 -08:00
parent 125de90a18
commit 9be848e5e2
16 changed files with 203 additions and 197 deletions

View File

@ -4,8 +4,8 @@ import os
import traceback
# Module imports
import cli
import config
import amanuensis.cli as cli
import amanuensis.config as config
def repl(args):

View File

@ -10,8 +10,8 @@
def server_commands(commands={}):
if commands: return commands
import cli.server
for name, func in vars(cli.server).items():
import amanuensis.cli.server
for name, func in vars(amanuensis.cli.server).items():
if name.startswith("command_"):
name = name[8:].replace("_", "-")
commands[name] = func
@ -19,8 +19,8 @@ def server_commands(commands={}):
def lexicon_commands(commands={}):
if commands: return commands
import cli.lexicon
for name, func in vars(cli.lexicon).items():
import amanuensis.cli.lexicon
for name, func in vars(amanuensis.cli.lexicon).items():
if name.startswith("command_"):
name = name[8:].replace("_", "-")
commands["lexicon-" + name] = func
@ -28,8 +28,8 @@ def lexicon_commands(commands={}):
def user_commands(commands={}):
if commands: return commands
import cli.user
for name, func in vars(cli.user).items():
import amanuensis.cli.user
for name, func in vars(amanuensis.cli.user).items():
if name.startswith("command_"):
name = name[8:].replace("_", "-")
commands["user-" + name] = func

View File

@ -43,10 +43,10 @@ def requires_lexicon(command):
subp_val = hasattr(cmd_args, "lexicon") and getattr(cmd_args, "lexicon")
val = subp_val or base_val or None
if not val:
import config
config.logger.error("This command requires specifying a lexicon")
from amanuensis.config import logger
logger.error("This command requires specifying a lexicon")
return -1
from lexicon import LexiconModel
from amanuensis.lexicon import LexiconModel
cmd_args.lexicon = val#LexiconModel.by(name=val).name
command(cmd_args)
augmented_command.__dict__['wrapper'] = True
@ -64,10 +64,10 @@ def requires_username(command):
subp_val = hasattr(cmd_args, "username") and getattr(cmd_args, "username")
val = subp_val or base_val or None
if not val:
import config
config.logger.error("This command requires specifying a user")
from amanuensis.config import logger
logger.error("This command requires specifying a user")
return -1
from user import UserModel
from amanuensis.user import UserModel
cmd_args.username = val#UserModel.by(name=val).name
command(cmd_args)
augmented_command.__dict__['wrapper'] = True
@ -84,7 +84,7 @@ def config_get(cfg, pathspec):
path is the full pathspec, unsplit
"""
import json
from config import logger
from amanuensis.config import logger
if pathspec is CONFIG_GET_ROOT_VALUE:
path = []
@ -105,7 +105,7 @@ def config_set(obj_id, cfg, set_tuple):
set_tuple is a tuple of the pathspec and the value
"""
import json
from config import logger
from amanuensis.config import logger
pathspec, value = set_tuple
if not pathspec:
logger.error("Path must be non-empty")

View File

@ -1,4 +1,4 @@
from cli.helpers import (
from amanuensis.cli.helpers import (
add_argument, no_argument, requires_lexicon, requires_username,
config_get, config_set, CONFIG_GET_ROOT_VALUE)
@ -17,9 +17,9 @@ def command_create(args):
settings are as desired before opening the lexicon for player joins.
"""
# Module imports
from config import logger
from lexicon.manage import valid_name, create_lexicon
from user import UserModel
from amanuensis.config import logger
from amanuensis.lexicon.manage import valid_name, create_lexicon
from amanuensis.user import UserModel
# Verify arguments
if not valid_name(args.lexicon):
@ -42,9 +42,9 @@ def command_delete(args):
Delete a lexicon and optionally its data
"""
# Module imports
from config import logger
from lexicon import LexiconModel
from lexicon.manage import delete_lexicon
from amanuensis.config import logger
from amanuensis.lexicon import LexiconModel
from amanuensis.lexicon.manage import delete_lexicon
# Verify arguments
lex = LexiconModel.by(name=args.lexicon)
@ -63,7 +63,7 @@ def command_list(args):
List all lexicons and their statuses
"""
# Module imports
from lexicon.manage import get_all_lexicons
from amanuensis.lexicon.manage import get_all_lexicons
# Internal call
lexicons = get_all_lexicons()
@ -91,8 +91,8 @@ def command_config(args):
Interact with a lexicon's config
"""
# Module imports
from config import logger, json_ro, json_rw
from lexicon import LexiconModel
from amanuensis.config import logger, json_ro, json_rw
from amanuensis.lexicon import LexiconModel
# Verify arguments
if args.get and args.set:
@ -123,10 +123,10 @@ def command_player_add(args):
Add a player to a lexicon
"""
# Module imports
from config import logger
from lexicon import LexiconModel
from lexicon.manage import add_player
from user import UserModel
from amanuensis.config import logger
from amanuensis.lexicon import LexiconModel
from amanuensis.lexicon.manage import add_player
from amanuensis.user import UserModel
# Verify arguments
u = UserModel.by(name=args.username)
@ -152,10 +152,10 @@ def command_player_remove(args):
they control but does not delete any character data.
"""
# Module imports
from config import logger
from lexicon import LexiconModel
from lexicon.manage import remove_player
from user import UserModel
from amanuensis.config import logger
from amanuensis.lexicon import LexiconModel
from amanuensis.lexicon.manage import remove_player
from amanuensis.user import UserModel
# Verify arguments
u = UserModel.by(name=args.username)
@ -181,8 +181,8 @@ def command_player_list(args):
"""
import json
# Module imports
from lexicon import LexiconModel
from user import UserModel
from amanuensis.lexicon import LexiconModel
from amanuensis.user import UserModel
# Verify arguments
lex = LexiconModel.by(name=args.lexicon)
@ -209,10 +209,10 @@ def command_char_create(args):
The specified player will be set as the character's player.
"""
# Module imports
from config import logger
from lexicon import LexiconModel
from lexicon.manage import add_character
from user import UserModel
from amanuensis.config import logger
from amanuensis.lexicon import LexiconModel
from amanuensis.lexicon.manage import add_character
from amanuensis.user import UserModel
# Verify arguments
u = UserModel.by(name=args.username)
@ -223,7 +223,7 @@ def command_char_create(args):
if lex is None:
logger.error("Could not find lexicon '{}'".format(args.lexicon))
return -1
# u in lx
# u in lx TODO
# Internal call
add_character(lex, u, {"name": args.charname})
@ -239,9 +239,9 @@ def command_char_delete(args):
they have contributed rather than deleting it.
"""
# Module imports
from config import logger
from lexicon import LexiconModel
from lexicon.manage import delete_character
from amanuensis.config import logger
from amanuensis.lexicon import LexiconModel
from amanuensis.lexicon.manage import delete_character
# Verify arguments
lex = LexiconModel.by(name=args.lexicon)
@ -259,7 +259,7 @@ def command_char_list(args):
"""
import json
# Module imports
from lexicon import LexiconModel
from amanuensis.lexicon import LexiconModel
# Verify arguments
lex = LexiconModel.by(name=args.lexicon)
@ -291,4 +291,7 @@ def command_publish_turn(args):
The --force flag bypasses the publish.quorum and publish.block_on_ready
settings.
"""
# Module imports
from amanuensis.config import logger
raise NotImplementedError() # TODO

View File

@ -1,6 +1,6 @@
import os
from cli.helpers import (
from amanuensis.cli.helpers import (
add_argument, no_argument,
config_get, config_set, CONFIG_GET_ROOT_VALUE)
@ -20,7 +20,7 @@ def command_init(args):
from the indexes will be deleted, and stale index entries will be removed.
"""
# Module imports
from config.init import create_config_dir
from amanuensis.config.init import create_config_dir
# Verify arguments
if args.refresh and not os.path.isdir(args.config_dir):
@ -39,13 +39,13 @@ def command_generate_secret(args):
been generated.
"""
import os
import config
# Module imports
from amanuensis.config import json_rw, logger
secret_key = os.urandom(32)
with config.json_rw("config.json") as cfg:
with json_rw("config.json") as cfg:
cfg['secret_key'] = secret_key.hex()
config.logger.info("Regenerated Flask secret key")
logger.info("Regenerated Flask secret key")
@add_argument("-a", "--address", default="127.0.0.1")
@ -57,13 +57,13 @@ def command_run(args):
The default Flask server is not secure, and should
only be used for development.
"""
import server
import config
from amanuensis.server import app
from amanuensis.config import get, logger
if config.get("secret_key") is None:
config.logger.error("Can't run server without a secret_key. Run generate-secret first")
if get("secret_key") is None:
logger.error("Can't run server without a secret_key. Run generate-secret first")
return -1
server.app.run(host=args.address, port=args.port)
app.run(host=args.address, port=args.port)
@add_argument("--get", metavar="PATHSPEC", dest="get",
@ -78,16 +78,17 @@ def command_config(args):
a dot-separated sequence of keys.
"""
import json
import config
# Module imports
from amanuensis.config import json_ro, json_rw, logger
if args.get and args.set:
config.logger.error("Specify one of --get and --set")
logger.error("Specify one of --get and --set")
return -1
if args.get:
with config.json_ro('config.json') as cfg:
with json_ro('config.json') as cfg:
config_get(cfg, args.get)
if args.set:
with config.json_rw('config.json') as cfg:
with json_rw('config.json') as cfg:
config_set("config", cfg, args.set)

View File

@ -1,6 +1,6 @@
import shutil
from cli.helpers import (
from amanuensis.cli.helpers import (
add_argument, no_argument, requires_username,
config_get, config_set, CONFIG_GET_ROOT_VALUE)
@ -12,26 +12,26 @@ def command_create(args):
Create a user
"""
import json
import user
import config
# Module imports
from amanuensis.config import logger, json_ro
from amanuensis.user import UserModel, valid_username, valid_email, create_user
# Verify or query parameters
if not user.valid_username(args.username):
config.logger.error("Invalid username: usernames may only contain alphanumeric characters, dashes, and underscores")
if not valid_username(args.username):
logger.error("Invalid username: usernames may only contain alphanumeric characters, dashes, and underscores")
return -1
if user.UserModel.by(name=args.username) is not None:
config.logger.error("Invalid username: username is already taken")
if UserModel.by(name=args.username) is not None:
logger.error("Invalid username: username is already taken")
return -1
if not args.displayname:
args.displayname = args.username
if not user.valid_email(args.email):
config.logger.error("Invalid email")
if not valid_email(args.email):
logger.error("Invalid email")
return -1
# Create user
new_user, tmp_pw = user.create_user(args.username, args.displayname, args.email)
with config.json_ro(new_user.config_path) as js:
new_user, tmp_pw = create_user(args.username, args.displayname, args.email)
with json_ro(new_user.config_path) as js:
print(json.dumps(js, indent=2))
print("Username: {}\nUser ID: {}\nPassword: {}".format(args.username, new_user.uid, tmp_pw))
@ -41,31 +41,33 @@ def command_delete(args):
Delete a user
"""
import os
# Module imports
from amanuensis.config import logger, prepend
import config
user_path = config.prepend('user', args.id)
user_path = prepend('user', args.id)
if not os.path.isdir(user_path):
config.logger.error("No user with that id")
logger.error("No user with that id")
return -1
else:
shutil.rmtree(user_path)
with config.json_rw('user', 'index.json') as j:
with json_rw('user', 'index.json') as j:
if args.id in j:
del j[uid]
# TODO
@no_argument
def command_list(args):
"""List all users"""
import os
# Module imports
from amanuensis.config import prepend, json_ro
import config
user_dirs = os.listdir(config.prepend('user'))
user_dirs = os.listdir(prepend('user'))
users = []
for uid in user_dirs:
if uid == "index.json": continue
with config.json_ro('user', uid, 'config.json') as user:
with json_ro('user', uid, 'config.json') as user:
users.append(user)
users.sort(key=lambda u: u['username'])
for user in users:
@ -83,24 +85,25 @@ def command_config(args):
Interact with a user's config
"""
import json
import config
from user import UserModel
# Module imports
from amanuensis.config import logger, json_ro, json_rw
from amanuensis.user import UserModel
if args.get and args.set:
config.logger.error("Specify one of --get and --set")
logger.error("Specify one of --get and --set")
return -1
u = UserModel.by(name=args.username)
if not u:
config.logger.error("User not found")
logger.error("User not found")
return -1
if args.get:
with config.json_ro('user', u.id, 'config.json') as cfg:
with json_ro('user', u.id, 'config.json') as cfg:
config_get(cfg, args.get)
if args.set:
with config.json_rw('user', u.id, 'config.json') as cfg:
with json_rw('user', u.id, 'config.json') as cfg:
config_set(u.id, cfg, args.set)
@add_argument("--username", help="The user to change password for")
@ -110,15 +113,15 @@ def command_passwd(args):
"""
import getpass
import os
import config
from user import UserModel
# Module imports
from amanuensis.config import logger
from amanuensis.user import UserModel
if not args.username:
args.username = input("Username: ")
u = UserModel.by(name=args.username)
if u is None:
config.logger.error("No user with username '{}'".format(args.username))
logger.error("No user with username '{}'".format(args.username))
return -1
pw = getpass.getpass("Password: ")
u.set_password(pw)

View File

@ -4,9 +4,9 @@ import logging
import os
# Module imports
from errors import MissingConfigError, MalformedConfigError
import config.init
import config.loader
from amanuensis.errors import MissingConfigError, MalformedConfigError
import amanuensis.config.init
import amanuensis.config.loader
# Environment variable name constants
@ -31,10 +31,10 @@ def init_config(args):
"""
global CONFIG_DIR, GLOBAL_CONFIG, logger
CONFIG_DIR = args.config_dir
config.init.verify_config_dir(CONFIG_DIR)
with config.loader.json_ro(os.path.join(CONFIG_DIR, "config.json")) as cfg:
amanuensis.config.init.verify_config_dir(CONFIG_DIR)
with amanuensis.config.loader.json_ro(os.path.join(CONFIG_DIR, "config.json")) as cfg:
GLOBAL_CONFIG = cfg
config.init.init_logging(args, GLOBAL_CONFIG['logging'])
amanuensis.config.init.init_logging(args, GLOBAL_CONFIG['logging'])
logger = logging.getLogger("amanuensis")
def get(key):
@ -47,13 +47,13 @@ def prepend(*path):
return joined
def open_sh(*path, mode):
return config.loader.open_sh(prepend(*path), mode)
return amanuensis.config.loader.open_sh(prepend(*path), mode)
def open_ex(*path, mode):
return config.loader.open_ex(prepend(*path), mode)
return amanuensis.config.loader.open_ex(prepend(*path), mode)
def json_ro(*path):
return config.loader.json_ro(prepend(*path))
return amanuensis.config.loader.json_ro(prepend(*path))
def json_rw(*path):
return config.loader.json_rw(prepend(*path))
return amanuensis.config.loader.json_rw(prepend(*path))

View File

@ -6,10 +6,10 @@ import os
import shutil
# Module imports
from errors import MissingConfigError, MalformedConfigError
import config
from config.loader import json_ro
import resources
from amanuensis.errors import MissingConfigError, MalformedConfigError
from amanuensis.config.loader import json_ro, json_rw
from amanuensis.resources import get_stream
def create_config_dir(config_dir, refresh=False):
"""
@ -18,23 +18,24 @@ def create_config_dir(config_dir, refresh=False):
from collections import OrderedDict
import fcntl
path = config.prepend
def prepend(*path):
joined = os.path.join(*path)
if not joined.startswith(config_dir):
joined = os.path.join(config_dir, joined)
return joined
# Create the directory if it doesn't exist.
if not os.path.isdir(config_dir):
os.mkdir(config_dir)
# Initialize the config dir without verification
config.CONFIG_DIR = config_dir
# The directory should be empty if we're not updating an existing one.
if len(os.listdir(config_dir)) > 0 and not refresh:
print("Directory {} is not empty".format(config_dir))
return -1
# Update or create global config.
def_cfg = resources.get_stream("global.json")
global_config_path = path("config.json")
def_cfg = get_stream("global.json")
global_config_path = prepend("config.json")
if refresh and os.path.isfile(global_config_path):
# We need to write an entirely different ordereddict to the config
# file, so we mimic the config.loader functionality manually.
@ -56,34 +57,34 @@ def create_config_dir(config_dir, refresh=False):
cfg_file.truncate()
fcntl.lockf(cfg_file, fcntl.LOCK_UN)
else:
with open(path("config.json"), 'wb') as f:
with open(prepend("config.json"), 'wb') as f:
f.write(def_cfg.read())
# Ensure pidfile exists.
if not os.path.isfile(path("pid")):
with open(path("pid"), 'w') as f:
if not os.path.isfile(prepend("pid")):
with open(prepend("pid"), 'w') as f:
f.write(str(os.getpid()))
# Ensure lexicon subdir exists.
if not os.path.isdir(path("lexicon")):
os.mkdir(path("lexicon"))
if not os.path.isfile(path("lexicon", "index.json")):
with open(path("lexicon", "index.json"), 'w') as f:
if not os.path.isdir(prepend("lexicon")):
os.mkdir(prepend("lexicon"))
if not os.path.isfile(prepend("lexicon", "index.json")):
with open(prepend("lexicon", "index.json"), 'w') as f:
json.dump({}, f)
# Ensure user subdir exists.
if not os.path.isdir(path("user")):
os.mkdir(path("user"))
if not os.path.isfile(path('user', 'index.json')):
with open(path('user', 'index.json'), 'w') as f:
if not os.path.isdir(prepend("user")):
os.mkdir(prepend("user"))
if not os.path.isfile(prepend('user', 'index.json')):
with open(prepend('user', 'index.json'), 'w') as f:
json.dump({}, f)
if refresh:
for dir_name in ('lexicon', 'user'):
# Clean up unindexed folders
with config.json_ro(dir_name, 'index.json') as index:
with json_ro(prepend(dir_name, 'index.json')) as index:
known = list(index.values())
entries = os.listdir(path(dir_name))
entries = os.listdir(prepend(dir_name))
for dir_entry in entries:
if dir_entry == "index.json":
continue
@ -91,12 +92,12 @@ def create_config_dir(config_dir, refresh=False):
continue
print("Removing unindexed folder: '{}/{}'"
.format(dir_name, dir_entry))
shutil.rmtree(path(dir_name, dir_entry))
shutil.rmtree(prepend(dir_name, dir_entry))
# Remove orphaned index listings
with config.json_rw(dir_name, 'index.json') as index:
with json_rw(prepend(dir_name, 'index.json')) as index:
for name, entry in index.items():
if not os.path.isdir(path(dir_name, entry)):
if not os.path.isdir(prepend(dir_name, entry)):
print("Removing stale {} index entry '{}: {}'"
.format(dir_name, name, entry))
del index[name]
@ -115,7 +116,7 @@ def verify_config_dir(config_dir):
if not os.path.isfile(global_config_path):
raise MissingConfigError("Config directory missing global config file: {}".format(config_dir))
# Check that global config file has all the default settings
def_cfg_s = resources.get_stream("global.json")
def_cfg_s = get_stream("global.json")
def_cfg = json.load(def_cfg_s)
with json_ro(global_config_path) as global_config_file:
for key in def_cfg.keys():

View File

@ -5,7 +5,7 @@ import json
import os
# Module imports
from errors import ReadOnlyError
from amanuensis.errors import ReadOnlyError
class AttrOrderedDict(OrderedDict):

View File

@ -1,8 +1,8 @@
import os
import time
from errors import InternalMisuseError, IndexMismatchError, MissingConfigError
import config
from amanuensis.errors import InternalMisuseError, IndexMismatchError, MissingConfigError
from amanuensis.config import prepend, json_ro, json_rw
class LexiconModel():
def by(lid=None, name=None):
@ -18,24 +18,24 @@ class LexiconModel():
if not lid and not name:
raise ValueError("One of lid or name must be not None")
if not lid:
with config.json_ro('lexicon', 'index.json') as index:
with json_ro('lexicon', 'index.json') as index:
lid = index.get(name)
if not lid:
return None
if not os.path.isdir(config.prepend('lexicon', lid)):
if not os.path.isdir(prepend('lexicon', lid)):
raise IndexMismatchError("lexicon={} lid={}".format(name, lid))
if not os.path.isfile(config.prepend('lexicon', lid, 'config.json')):
if not os.path.isfile(prepend('lexicon', lid, 'config.json')):
raise MissingConfigError("lid={}".format(lid))
return LexiconModel(lid)
def __init__(self, lid):
if not os.path.isdir(config.prepend('lexicon', lid)):
if not os.path.isdir(prepend('lexicon', lid)):
raise ValueError("No lexicon with lid {}".format(lid))
if not os.path.isfile(config.prepend('lexicon', lid, 'config.json')):
if not os.path.isfile(prepend('lexicon', lid, 'config.json')):
raise FileNotFoundError("Lexicon {} missing config.json".format(lid))
self.id = str(lid)
self.config_path = config.prepend('lexicon', lid, 'config.json')
with config.json_ro(self.config_path) as j:
self.config_path = prepend('lexicon', lid, 'config.json')
with json_ro(self.config_path) as j:
self.config = j
def __getattr__(self, key):
@ -45,7 +45,7 @@ class LexiconModel():
def log(self, message):
now = int(time.time())
with config.json_rw(self.config_path) as j:
with json_rw(self.config_path) as j:
j['log'].append([now, message])
def status(self):

View File

@ -9,10 +9,10 @@ import shutil
import time
import uuid
import config
from config.loader import AttrOrderedDict
import lexicon
import resources
from amanuensis.config import prepend, json_rw, json_ro, logger
from amanuensis.config.loader import AttrOrderedDict
from amanuensis.lexicon import LexiconModel
from amanuensis.resources import get_stream
def valid_name(name):
"""
@ -34,28 +34,28 @@ def create_lexicon(name, editor):
# Create the lexicon directory and initialize it with a blank lexicon
lid = uuid.uuid4().hex
lex_dir = config.prepend("lexicon", lid)
lex_dir = prepend("lexicon", lid)
os.mkdir(lex_dir)
with resources.get_stream("lexicon.json") as s:
with open(config.prepend(lex_dir, 'config.json'), 'wb') as f:
with get_stream("lexicon.json") as s:
with open(prepend(lex_dir, 'config.json'), 'wb') as f:
f.write(s.read())
# Fill out the new lexicon
with config.json_rw(lex_dir, 'config.json') as cfg:
with json_rw(lex_dir, 'config.json') as cfg:
cfg['lid'] = lid
cfg['name'] = name
cfg['editor'] = editor.uid
cfg['time']['created'] = int(time.time())
# Update the index with the new lexicon
with config.json_rw('lexicon', 'index.json') as index:
with json_rw('lexicon', 'index.json') as index:
index[name] = lid
# Load the Lexicon and log creation
l = lexicon.LexiconModel(lid)
l = LexiconModel(lid)
l.log("Lexicon created")
config.logger.info("Created Lexicon {0.name}, ed. {1.displayname} ({0.id})".format(
logger.info("Created Lexicon {0.name}, ed. {1.displayname} ({0.id})".format(
l, editor))
# Add the editor
@ -82,7 +82,7 @@ def delete_lexicon(lex, purge=False):
raise ValueError("Invalid lexicon: '{}'".format(lex))
# Delete the lexicon from the index
with config.json_rw('lexicon', 'index.json') as j:
with json_rw('lexicon', 'index.json') as j:
if lex.id in j:
del j[lex.id]
@ -91,7 +91,7 @@ def delete_lexicon(lex, purge=False):
raise NotImplementedError()
# Delete the lexicon config
lex_path = config.prepend('lexicon', lex.id)
lex_path = prepend('lexicon', lex.id)
shutil.rmtree(lex_path)
@ -100,11 +100,11 @@ def get_all_lexicons():
Loads each lexicon in the lexicon index
"""
# Get all the lexicon ids in the index
with config.json_ro('lexicon', 'index.json') as index:
with json_ro('lexicon', 'index.json') as index:
lids = list(index.values())
# Load all of the lexicons
lexes = list(map(lambda id: lexicon.LexiconModel.by(lid=id), lids))
lexes = list(map(lambda id: LexiconModel.by(lid=id), lids))
return lexes
@ -145,7 +145,7 @@ def add_player(lex, player):
raise ValueError("Invalid player: '{}'".format(player))
# Idempotently add player
with config.json_rw(lex.config_path) as cfg:
with json_rw(lex.config_path) as cfg:
if player.id not in cfg.join.joined:
cfg.join.joined.append(player.id)
# Log to the lexicon's log
@ -165,7 +165,7 @@ def remove_player(lex, player):
raise ValueError("Can't remove the editor '{}' from lexicon '{}'".format(player.username, lex.name))
# Idempotently remove player
with config.json_rw(lex.config_path) as cfg:
with json_rw(lex.config_path) as cfg:
if player.id in cfg.join.joined:
cfg.join.joined.remove(player.id)
@ -190,7 +190,7 @@ def add_character(lex, player, charinfo={}):
raise ValueError("Duplicate character name: '{}'".format(charinfo))
# Load the character template
with resources.get_stream('character.json') as template:
with get_stream('character.json') as template:
character = json.load(template, object_pairs_hook=AttrOrderedDict)
# Fill out the character's information
@ -200,7 +200,7 @@ def add_character(lex, player, charinfo={}):
character.signature = charinfo.get("signature") or ("~" + character.name)
# Add the character to the lexicon
with config.json_rw(lex.config_path) as cfg:
with json_rw(lex.config_path) as cfg:
cfg.character.new(character.cid, character)
@ -221,5 +221,5 @@ def delete_character(lex, charname):
char = matches[0]
# Remove character from character list
with config.json_rw(lex.config_path) as cfg:
with json_rw(lex.config_path) as cfg:
del cfg.character[char.cid]

View File

@ -3,15 +3,15 @@ import os
from flask import Flask, render_template
from flask_login import LoginManager
import config
from server.auth import get_bp as get_auth_bp
from server.home import get_bp as get_home_bp
from server.lexicon import get_bp as get_lex_bp
from amanuensis.config import get
from amanuensis.server.auth import get_bp as get_auth_bp
from amanuensis.server.home import get_bp as get_home_bp
from amanuensis.server.lexicon import get_bp as get_lex_bp
# Flask app init
static_root = os.path.abspath(config.get("static_root"))
static_root = os.path.abspath(get("static_root"))
app = Flask(__name__, template_folder="../templates", static_folder=static_root)
app.secret_key = bytes.fromhex(config.get('secret_key'))
app.secret_key = bytes.fromhex(get('secret_key'))
app.jinja_options['trim_blocks'] = True
app.jinja_options['lstrip_blocks'] = True

View File

@ -4,8 +4,8 @@ from wtforms import StringField, PasswordField, BooleanField, SubmitField
from wtforms.validators import DataRequired
from flask_login import current_user, login_user, logout_user, login_required
import config
from user import UserModel
from amanuensis.config import logger
from amanuensis.user import UserModel
class LoginForm(FlaskForm):
username = StringField('Username', validators=[DataRequired()])
@ -30,7 +30,7 @@ def get_bp(login_manager):
if u is not None and u.check_password(form.password.data):
remember_me = form.remember.data
login_user(u, remember=remember_me)
config.logger.info("Logged in user '{}' ({})".format(
logger.info("Logged in user '{}' ({})".format(
u.username, u.uid))
return redirect(url_for('home.home'))
flash("Login not recognized")

View File

@ -6,9 +6,7 @@ from flask_login import login_required, current_user
from flask_wtf import FlaskForm
from wtforms import TextAreaField, SubmitField, StringField
import config
import user
import lexicon
from amanuensis.config import json_ro
class AdminDashboardForm(FlaskForm):
lexiconName = StringField("Lexicon name")
@ -42,10 +40,10 @@ def get_bp():
if form.lexiconName.data:
lid = None
with config.json_ro('lexicon', 'index.json') as index:
with json_ro('lexicon', 'index.json') as index:
lid = index.get(form.lexiconName.data)
if lid is not None:
with config.json_ro('lexicon', lid, 'config.json') as cfg:
with json_ro('lexicon', lid, 'config.json') as cfg:
form.configText.data = json.dumps(cfg, indent=2)
form.lexiconName.data = ""
elif form.configText.data:

View File

@ -6,16 +6,16 @@ from flask_login import login_required, current_user
from flask_wtf import FlaskForm
from wtforms import TextAreaField, SubmitField
import config
from config.loader import ReadOnlyOrderedDict
import user
import lexicon
from amanuensis.config import json_ro, open_ex
from amanuensis.config.loader import ReadOnlyOrderedDict
from amanuensis.lexicon import LexiconModel
from amanuensis.user import UserModel
def lexicon_param(route):
@wraps(route)
def with_lexicon(name):
g.lexicon = lexicon.LexiconModel.by(name=name)
g.lexicon = LexiconModel.by(name=name)
if g.lexicon is None:
flash("Couldn't find a lexicon with the name '{}'".format(name))
return redirect(url_for("home.home"))
@ -63,7 +63,7 @@ def get_bp():
# Load the config for the lexicon on load
if not form.is_submitted():
with config.json_ro(g.lexicon.config_path) as cfg:
with json_ro(g.lexicon.config_path) as cfg:
form.configText.data = json.dumps(cfg, indent=2)
return render_template("lexicon/session_edit.html", form=form)
@ -78,7 +78,7 @@ def get_bp():
# TODO
# Write the new config
form.submit.submitted = False
with config.open_ex(g.lexicon.config_path, mode='w') as f:
with open_ex(g.lexicon.config_path, mode='w') as f:
json.dump(cfg, f, indent='\t')
flash("Config updated")
return redirect(url_for('lexicon.session_edit', name=name))

View File

@ -6,10 +6,10 @@ import uuid
from flask_login import UserMixin
from werkzeug.security import generate_password_hash, check_password_hash
from errors import InternalMisuseError, MissingConfigError, IndexMismatchError
import config
import resources
import lexicon.manage
from amanuensis.errors import InternalMisuseError, MissingConfigError, IndexMismatchError
from amanuensis.config import prepend, json_ro, json_rw
from amanuensis.resources import get_stream
from amanuensis.lexicon.manage import get_all_lexicons
class UserModel(UserMixin):
@staticmethod
@ -26,21 +26,21 @@ class UserModel(UserMixin):
if not uid and not name:
raise ValueError("One of uid or name must be not None")
if not uid:
with config.json_ro('user', 'index.json') as index:
with json_ro('user', 'index.json') as index:
uid = index.get(name)
if not uid:
return None
if not os.path.isdir(config.prepend('user', uid)):
if not os.path.isdir(prepend('user', uid)):
raise IndexMismatchError("username={} uid={}".format(name, uid))
if not os.path.isfile(config.prepend('user', uid, 'config.json')):
if not os.path.isfile(prepend('user', uid, 'config.json')):
raise MissingConfigError("uid={}".format(uid))
return UserModel(uid)
def __init__(self, uid):
"""User model initializer, assume all checks were done by by()"""
self.id = str(uid) # Flask-Login checks for this
self.config_path = config.prepend('user', uid, 'config.json')
with config.json_ro(self.config_path) as j:
self.config_path = prepend('user', uid, 'config.json')
with json_ro(self.config_path) as j:
self.config = j
def __getattr__(self, key):
@ -50,17 +50,17 @@ class UserModel(UserMixin):
def set_password(self, pw):
h = generate_password_hash(pw)
with config.json_rw(self.config_path) as j:
with json_rw(self.config_path) as j:
j['password'] = h
def check_password(self, pw):
with config.json_ro(self.config_path) as j:
with json_ro(self.config_path) as j:
return check_password_hash(j['password'], pw)
def lexicons_in(self):
return [
lex
for lex in lexicon.manage.get_all_lexicons()
for lex in get_all_lexicons()
if self.id in lex.join.joined
]
@ -87,14 +87,14 @@ def create_user(username, displayname, email):
# Create the user directory and initialize it with a blank user
uid = uuid.uuid4().hex
user_dir = config.prepend("user", uid)
user_dir = prepend("user", uid)
os.mkdir(user_dir)
with resources.get_stream("user.json") as s:
with open(config.prepend(user_dir, 'config.json'), 'wb') as f:
with get_stream("user.json") as s:
with open(prepend(user_dir, 'config.json'), 'wb') as f:
f.write(s.read())
# Fill out the new user
with config.json_rw(user_dir, 'config.json') as cfg:
with json_rw(user_dir, 'config.json') as cfg:
cfg.uid = uid
cfg.username = username
cfg.displayname = displayname
@ -102,7 +102,7 @@ def create_user(username, displayname, email):
cfg.created = int(time.time())
# Update the index with the new user
with config.json_rw('user', 'index.json') as index:
with json_rw('user', 'index.json') as index:
index[username] = uid
# Set a temporary password