eos-parental-controls-client: Add a ‘set’ command

This allows the app filter to be set, using the new library API for it.

Signed-off-by: Philip Withnall <withnall@endlessm.com>

https://phabricator.endlessm.com/T24025
This commit is contained in:
Philip Withnall 2018-10-12 16:48:29 +13:00
parent 2a7d99c630
commit f68e3fa527
1 changed files with 95 additions and 9 deletions

View File

@ -72,6 +72,46 @@ def __get_app_filter_or_error(user_id, interactive):
raise SystemExit(EXIT_PERMISSION_DENIED) raise SystemExit(EXIT_PERMISSION_DENIED)
def __set_app_filter(user_id, app_filter, interactive):
"""Set the app filter for `user_id` off the bus.
If `interactive` is `True`, interactive polkit authorisation dialogues will
be allowed. An exception will be raised on failure."""
finished = False
exception = None
def __set_cb(obj, result, user_data):
nonlocal finished, exception
try:
EosParentalControls.set_app_filter_finish(result)
finished = True
except Exception as e:
exception = e
EosParentalControls.set_app_filter_async(
connection=None, user_id=user_id, app_filter=app_filter,
allow_interactive_authorization=interactive, cancellable=None,
callback=__set_cb, user_data=None)
context = GLib.MainContext.default()
while not finished and not exception:
context.iteration(True)
if exception:
raise exception
def __set_app_filter_or_error(user_id, app_filter, interactive):
"""Wrapper around __set_app_filter() which prints an error and raises
SystemExit, rather than an internal exception."""
try:
__set_app_filter(user_id, app_filter, interactive)
except GLib.Error as e:
print('Error setting app filter for user {}: {}'.format(
user_id, e.message), file=sys.stderr)
raise SystemExit(EXIT_PERMISSION_DENIED)
def __lookup_user_id(user): def __lookup_user_id(user):
"""Convert a command-line specified username or ID into a user ID. If """Convert a command-line specified username or ID into a user ID. If
`user` is empty, use the current user ID. `user` is empty, use the current user ID.
@ -95,23 +135,33 @@ def __lookup_user_id_or_error(user):
raise SystemExit(EXIT_INVALID_OPTION) raise SystemExit(EXIT_INVALID_OPTION)
oars_value_mapping = {
EosParentalControls.AppFilterOarsValue.UNKNOWN: "unknown",
EosParentalControls.AppFilterOarsValue.NONE: "none",
EosParentalControls.AppFilterOarsValue.MILD: "mild",
EosParentalControls.AppFilterOarsValue.MODERATE: "moderate",
EosParentalControls.AppFilterOarsValue.INTENSE: "intense",
}
def __oars_value_to_string(value): def __oars_value_to_string(value):
"""Convert an EosParentalControls.AppFilterOarsValue to a human-readable """Convert an EosParentalControls.AppFilterOarsValue to a human-readable
string.""" string."""
mapping = {
EosParentalControls.AppFilterOarsValue.UNKNOWN: "unknown",
EosParentalControls.AppFilterOarsValue.NONE: "none",
EosParentalControls.AppFilterOarsValue.MILD: "mild",
EosParentalControls.AppFilterOarsValue.MODERATE: "moderate",
EosParentalControls.AppFilterOarsValue.INTENSE: "intense",
}
try: try:
return mapping[value] return oars_value_mapping[value]
except KeyError: except KeyError:
return "invalid (OARS value {})".format(value) return "invalid (OARS value {})".format(value)
def __oars_value_from_string(value_str):
"""Convert a human-readable string to an
EosParentalControls.AppFilterOarsValue."""
for k, v in oars_value_mapping.items():
if v == value_str:
return k
raise KeyError('Unknown OARS value {}'.format(value_str))
def command_get(user, quiet=False, interactive=True): def command_get(user, quiet=False, interactive=True):
"""Get the app filter for the given user.""" """Get the app filter for the given user."""
user_id = __lookup_user_id_or_error(user) user_id = __lookup_user_id_or_error(user)
@ -149,6 +199,30 @@ def command_oars_section(user, section, quiet=False, interactive=True):
section, user_id, __oars_value_to_string(value))) section, user_id, __oars_value_to_string(value)))
def command_set(user, app_filter_args=None, quiet=False, interactive=True):
"""Set the app filter for the given user."""
user_id = __lookup_user_id_or_error(user)
builder = EosParentalControls.AppFilterBuilder.new()
for arg in app_filter_args:
if '=' in arg:
[section, value_str] = arg.split('=', 2)
try:
value = __oars_value_from_string(value_str)
except KeyError:
print('Unknown OARS value {}'.format(value_str),
file=sys.stderr)
raise SystemExit(EXIT_INVALID_OPTION)
builder.set_oars_value(section, value)
else:
builder.blacklist_path(arg)
app_filter = builder.end()
__set_app_filter_or_error(user_id, app_filter, interactive)
print('App filter for user {} set'.format(user_id))
def main(): def main():
# Parse command line arguments # Parse command line arguments
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
@ -204,6 +278,18 @@ def main():
'user)') 'user)')
parser_oars_section.add_argument('section', help='OARS section to get') parser_oars_section.add_argument('section', help='OARS section to get')
# set command
parser_set = subparsers.add_parser('set', parents=[common_parser],
help='set current parental controls '
'settings')
parser_set.set_defaults(function=command_set)
parser_set.add_argument('user', default='', nargs='?',
help='user ID or username to get the app filter '
'for (default: current user)')
parser_set.add_argument('app_filter_args', nargs='*',
help='paths to blacklist and OARS section=value '
'pairs to store')
# Parse the command line arguments and run the subcommand. # Parse the command line arguments and run the subcommand.
args = parser.parse_args() args = parser.parse_args()
args_dict = dict((k, v) for k, v in vars(args).items() if k != 'function') args_dict = dict((k, v) for k, v in vars(args).items() if k != 'function')