master.py: reorganize commands (#82)

This commit is contained in:
Lephe 2021-07-08 17:25:14 +02:00
parent f848615ff1
commit b31ed9bec2
Signed by untrusted user: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
1 changed files with 114 additions and 155 deletions

269
master.py
View File

@ -17,94 +17,46 @@ from PIL import Image
help_msg = """
This is the Planète Casio master shell. Type 'exit' or C-D to leave.
Type a category name to see a list of elements. Available categories are:
Listing commands:
members Show registered community members
groups Show privilege groups
forums Show forum tree
trophies Show trophies
'members' Registered community members
'groups' Privilege groups
'trophies' Trophies
'trophy-members' Trophies owned by members
'forums' Forum tree
For each category, an argument can be specified:
* 'clear' will remove all entries in the category (destroys a lot of data!)
* 'update' will update from the model in app/data/, when applicable
(currently available on: forums, groups)
Type 'create-common-accounts' to recreate 'Planète Casio' and 'GLaDOS'
Type 'add-group <member> #<group-id>' to add a new member to a group.
Type 'create-trophies' to reset trophies and titles and their icons.
Type 'enable-user' to enable a email-disabled account.
Install and update commands:
update-groups Create or update groups from app/data/
update-forums Create or update the forum tree from app/data/
update-trophies Create or update trophies
generate-trophy-icons Regenerate all trophy icons
create-common-accounts Remove and recreate 'Planète Casio' and 'GLaDOS'
add-group <member> #<id> Add <member> to group #<id> (presumably admins)
enable-user <member> Manually confirm member's email address
"""
#
# Category viewers
# Listing commands
#
def members(*args):
if args == ("clear",):
for m in Member.query.all():
m.delete()
db.session.commit()
print("Removed all members.")
return
for m in Member.query.all():
print(m)
def groups(*args):
if args == ("clear",):
for g in Group.query.all():
g.delete()
db.session.commit()
print("Removed all groups.")
return
if args == ("update",):
update_groups()
return
for g in Group.query.all():
print(f"#{g.id} {g.name}")
def trophies(*args):
if args == ("clear",):
for t in Trophy.query.all():
db.session.delete(t)
db.session.commit()
print("Removed all trophies.")
return
for t in Trophy.query.all():
print(t)
def trophy_members(*args):
for t in Trophy.query.all():
if t.owners == []:
continue
print(t)
for m in t.owners:
print(f" {m}")
def forums(*args):
if args == ("clear",):
for f in Forum.query.all():
db.session.delete(f)
db.session.commit()
print("Removed all forums.")
return
if args == ("update",):
update_forums()
return
for f in Forum.query.all():
parent = f"in {f.parent.url}" if f.parent is not None else "root"
print(f"{f.url} ({parent}) [{f.prefix}]: {f.name}")
print(f" {f.descr}")
def trophies(*args):
for t in Trophy.query.all():
print(t)
#
# Creation and edition
# Install and update commands
#
def update_groups():
@ -151,90 +103,6 @@ def update_groups():
db.session.commit()
def create_common_accounts():
# Clean up common accounts
for name in "PlanèteCasio GLaDOS".split():
m = Member.query.filter_by(name=name).first()
if m is not None:
m.delete()
# Recreate theme
def addgroup(member, group):
g = Group.query.filter_by(name=group).first()
if g is not None:
member.groups.append(g)
m = Member("PlanèteCasio", "contact@planet-casio.com", "nologin")
addgroup(m, "Compte communautaire")
addgroup(m, "No login")
db.session.add(m)
m = Member("GLaDOS", "glados@aperture.science", "nologin")
m.xp = 1338
addgroup(m, "Robot")
addgroup(m, "No login")
db.session.add(m)
db.session.commit()
db.session.add(SpecialPrivilege(m, "edit.posts"))
db.session.add(SpecialPrivilege(m, "shoutbox.ban"))
db.session.commit()
def create_trophies():
# Clean up trophies
trophies("clear")
# Create base trophies
tr = []
with open(os.path.join(app.root_path, "data", "trophies.yaml")) as fp:
tr = yaml.safe_load(fp.read())
for t in tr:
description = t.get("description", "")
if t["is_title"]:
trophy = Title(t["name"], description, t["hidden"],
t.get("css", ""))
else:
trophy = Trophy(t["name"], description, t["hidden"])
db.session.add(trophy)
db.session.commit()
print(f"Created {len(tr)} trophies.")
# Create their icons
create_trophies_icons()
def create_trophies_icons():
tr = []
with open(os.path.join(app.root_path, "data", "trophies.yaml")) as fp:
tr = yaml.safe_load(fp.read())
names = [slugify.slugify(t["name"]) for t in tr]
src = os.path.join(app.root_path, "data", "trophies.png")
dst = os.path.join(app.root_path, "static", "images", "trophies")
try:
os.mkdir(dst)
except FileExistsError:
pass
img = Image.open(src)
def trophy_iterator(img):
for y in range(img.height // 26):
for x in range(img.width // 26):
icon = img.crop((26*x+1, 26*y+1, 26*x+25, 26*y+25))
# Skip blank squares in the source image
if len(icon.getcolors()) > 1:
yield icon.resize((48,48))
for (name, icon) in zip(names, trophy_iterator(img)):
icon.save(os.path.join(dst, f"{name}.png"))
def update_forums():
# Get current forums
existing = Forum.query.all()
@ -286,6 +154,91 @@ def update_forums():
db.session.commit()
def update_trophies():
raise Exception("Not implemented as data-lossless for now")
# Clean up trophies
trophies("clear")
# Create base trophies
tr = []
with open(os.path.join(app.root_path, "data", "trophies.yaml")) as fp:
tr = yaml.safe_load(fp.read())
for t in tr:
description = t.get("description", "")
if t["is_title"]:
trophy = Title(t["name"], description, t["hidden"],
t.get("css", ""))
else:
trophy = Trophy(t["name"], description, t["hidden"])
db.session.add(trophy)
db.session.commit()
print(f"Created {len(tr)} trophies.")
def generate_trophy_icons():
tr = []
with open(os.path.join(app.root_path, "data", "trophies.yaml")) as fp:
tr = yaml.safe_load(fp.read())
names = [slugify.slugify(t["name"]) for t in tr]
src = os.path.join(app.root_path, "data", "trophies.png")
dst = os.path.join(app.root_path, "static", "images", "trophies")
try:
os.mkdir(dst)
except FileExistsError:
pass
img = Image.open(src)
def trophy_iterator(img):
for y in range(img.height // 26):
for x in range(img.width // 26):
icon = img.crop((26*x+1, 26*y+1, 26*x+25, 26*y+25))
# Skip blank squares in the source image
if len(icon.getcolors()) > 1:
yield icon.resize((48,48))
for (name, icon) in zip(names, trophy_iterator(img)):
icon.save(os.path.join(dst, f"{name}.png"))
def create_common_accounts():
# Clean up common accounts
for name in "PlanèteCasio GLaDOS".split():
m = Member.query.filter_by(name=name).first()
if m is not None:
m.delete()
# Recreate theme
def addgroup(member, group):
g = Group.query.filter_by(name=group).first()
if g is not None:
member.groups.append(g)
m = Member("PlanèteCasio", "contact@planet-casio.com", "nologin")
addgroup(m, "Compte communautaire")
addgroup(m, "No login")
db.session.add(m)
m = Member("GLaDOS", "glados@aperture.science", "nologin")
m.xp = 1338
addgroup(m, "Robot")
addgroup(m, "No login")
db.session.add(m)
db.session.commit()
db.session.add(SpecialPrivilege(m, "edit.posts"))
db.session.add(SpecialPrivilege(m, "shoutbox.ban"))
db.session.commit()
def add_group(member, group):
if group[0] != "#":
print(f"error: group id {group} should start with '#'")
@ -305,6 +258,7 @@ def add_group(member, group):
db.session.add(m)
db.session.commit()
def enable_user(member):
norm = unicode_names.normalize(member)
m = Member.query.filter_by(norm=norm).first()
@ -324,12 +278,13 @@ commands = {
"exit": lambda: sys.exit(0),
"members": members,
"groups": groups,
"trophies": trophies,
"trophy-members": trophy_members,
"forums": forums,
"trophies": trophies,
"update-groups": update_groups,
"update-forums": update_forums,
"update-trophies": update_trophies,
"generate-trophy-icons": generate_trophy_icons,
"create-common-accounts": create_common_accounts,
"create-trophies": create_trophies,
"create-trophies-icons": create_trophies_icons,
"add-group": add_group,
"enable-user": enable_user,
}
@ -352,6 +307,10 @@ else:
try:
cmd = input("@> ").split()
except EOFError:
print("^D")
sys.exit(0)
except KeyboardInterrupt:
print("^C")
sys.exit(0)
if cmd: