diff --git a/master.py b/master.py index 7e8ef9f..7019bda 100755 --- a/master.py +++ b/master.py @@ -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 #' 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 # Add to group # (presumably admins) + enable-user 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: