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 fbaf3c0460
commit 02dfdac221
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)
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):
"""Convert a command-line specified username or ID into a user ID. If
`user` is empty, use the current user ID.
@ -95,23 +135,33 @@ def __lookup_user_id_or_error(user):
raise SystemExit(EXIT_INVALID_OPTION)
def __oars_value_to_string(value):
"""Convert an EosParentalControls.AppFilterOarsValue to a human-readable
string."""
mapping = {
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):
"""Convert an EosParentalControls.AppFilterOarsValue to a human-readable
string."""
try:
return mapping[value]
return oars_value_mapping[value]
except KeyError:
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):
"""Get the app filter for the given 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)))
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():
# Parse command line arguments
parser = argparse.ArgumentParser(
@ -204,6 +278,18 @@ def main():
'user)')
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.
args = parser.parse_args()
args_dict = dict((k, v) for k, v in vars(args).items() if k != 'function')