-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
adminui unification #63
Comments
One quick thought: If |
Another idea: New Custom |
Also, I'm currently planning on implementing this in |
One tricky issue is that right now the def admin(ctx, msg, modconf, text):
use(modconf[...]) becomes: def admin(ctx, msg, botconf, field, desc, text):
modconf = botconf[field]
use(modconf[...]) with a slightly awkward transition from Another issue with the simplest approach (literally having admin.default use adminui.fields) is the change in action from "Choose a module" (etc.) to the hard-coded "Choose a field". |
…ds instead of custom code to select a module. This changes the signature of all MODULE.admin functions to contain the parent's conf object (so modconf becomes botconf), the current frame's field's name in that conf (modconf = botconf[field]), and the current frame's description (currently unused). Followups will likely continue this to have admin.default use adminui.fields even earlier (for bot selection), as well as places like moderator.admin (for group selection), but doing so would currently require the functions to be split into multiple callables. Thought should be given as to whether to go ahead and break adminui.fields into a callable adminui.Menu (as sort of a partial function). This also requires field descriptions to be calculated every time the fields are processed, even if the descriptions are never used. Thought should be given as to whether to actually separate the field name and type list from the description list, or to maybe do something like: ('fieldname', adminui.fieldtype, lambda: 'field description'), i.e. make the desc a callable. There's a similar concern about a theoretical invalid_msg and empty_msg standardization for adminui.fields (or adminui.Menu): Right now admin.default actually opens a file on disk every time it displays the theoretical invalid_msg. If this becomes a string passed to adminui.fields/Menu, the file will be read every time the user navigates anywhere within /admin (not just at the top-level bot selection menu). See #63.
I keep referring to the current location within botconf as the "frame", it might make sense to actually create a new structure called Frame (versus overloading "context") passed through the call signature to keep track of everything. The simplest gain would be to store It could also store both (FWIW, I don't think That all is probably a good first iteration, then followups might go ahead and move And for now this will likely be instantiated in |
…e container. This is largely mechanical, though I did move the step through subconf from the call to adminui.fields into adminui.fields itself. I also snuck in a tiny fix to adminui.timezone (displaying the actual field name instead of the fixed string "timezone"). See #63.
If Initially, just use this in place of current redundant logging throughout adminui (and MODULE.admin?), but eventually either somehow hook this into |
(Alternatively to moving |
Menu
Both |
New plan for menu = adminui.Menu(...)
if menu.dispatch(ctx, msg, frame):
return
msg.add('...')
with open('file') as f:
msg.add(f.read())
...
menu.display(ctx, msg, frame)
Going a step further: menu = adminui.Menu(...)
frame, handler = menu.select(ctx, msg, frame)
if handler: # frame is now the subframe.
return handler(ctx, msg, frame)
msg.add(...)
...
menu.display(ctx, msg, frame) which will allow things like menu = adminui.Menu(... bot list)
frame, handler = menu.select(ctx, msg, frame)
if not handler:
msg.add(...)
return menu.display(ctx, msg, frame)
ctx.targetbotuser = frame.field
...
# handler is ignored (can just be True in the first Menu).
menu = adminui.Menu(... module list)
if not menu.dispatch(ctx, msg, frame):
msg.add(... module info)
menu.display(ctx, msg, frame) where def dispatch(self, ctx, msg, frame):
frame, handler = self.select(ctx, msg, frame)
if handler:
msg.path(frame.field)
handler(ctx, msg, frame)
if msg.action:
return True
msg.pathpop() |
…a new adminui.Menu. A followup will change Menu.handle to call msg.add(frame.desc) before self.display. Additional followups may make more-invasive UI changes like calling msg.add(frame.desc) more often, styling it differently, and/or doing things like msg.add(msg.action + ':') as the last thing before adding menu buttons. See #63.
Convert modules.echo.admin to use adminui.Menu (see #63).
metabot.modules.countdown.admin exposes an interesting problem: A user enters menu = adminui.Menu()
now = time.time()
for command, timestamp in sorted(frame.value.items()):
menu.add(command, desc=format_delta(timestamp - now))
frame, handler = menu.select(ctx, msg, frame, create=True)
if not handler:
msg.action = 'Choose a command'
msg.add(
"Type the name of a command to add (like <code>days</code>\u2014don't include a slash "
'at the beginning!), or select an existing countdown to remove.')
return menu.display(ctx, msg, frame, 'command') would mean the command, _, timestamp = frame.text.partition(' ')
command = command.lower()
if command and timestamp:
if timestamp.isdigit():
...
modconf[command] = timestamp
command = timestamp = None |
There's definitely a way to do this, like: newframe, handler = menu.select(ctx, msg, frame, create=True)
if handler:
if newframe.text.isdigit():
adminui.set_log(msg, newframe, int(newframe.text))
elif newframe.text in ('-', ...):
adminui.set_log(msg, newframe, None)
else:
if newframe.text:
msg.add("Can't ...")
return msg.add('This is a little technical ...')
msg.add('Type the name of ...')
menu.display(ctx, msg, frame, 'command') however, going back to a different alternative, it might be nice to add a |
Wee, this works except that the newly created command doesn't show up in
This also exposes the general issue that whenever |
Somewhat continuing from c4a74ce and 8ba1c4b, redo the
/admin
system (MODULE.admin and adminui.FIELDTYPE) to be totally uniform.metabot.modules.admin.default
will likely call directly intometabot.util.adminui.fields
rather than handling both bot username selection and module selection in custom logic before directly calling MODULE.admin. All of the various MODULE.admin functions (likemetabot.modules.admin.admin
itself) will be changed from amoddispatch
-style signature (ctx, msg, modconf
) to anadminui
-style signature (ctx, msg, subconf, field, fielddesc, text
). Rather than calling adminui.fields explicitly, all MODULE.admin and adminui.FIELDTYPE functions will return thefieldset
parameter (calledfields
in most current consumers). If instead it returnsNone
, the dispatcher (either adminui.fields itself or admin.default) will assume some action was finalized and use its parent'sfieldset
instead.UI-wise, I think this should be 100% invisible. Code-maintainability-wise, this should be a significant short-term improvement and also a great step toward #23-464266888 ("We could replace
module.admin()
withmodule.SCHEMA
").The text was updated successfully, but these errors were encountered: