Coverage for /home/antoine/projects/xpra-git/dist/python3/lib64/python/xpra/server/control_command.py : 39%
Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# -*- coding: utf-8 -*-
2# This file is part of Xpra.
3# Copyright (C) 2015-2020 Antoine Martin <antoine@xpra.org>
4# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
5# later version. See the file COPYING for details.
7from xpra.log import Logger
8from xpra.util import csv, engs
10log = Logger("util", "command")
13class ControlError(Exception):
15 def __init__(self, msg, help_text=None, code=127):
16 super().__init__(msg)
17 self.help = help_text
18 self.code = code
21class ControlCommand:
22 """ Utility superclass for control commands """
24 def __init__(self, name, help_text=None, run=None):
25 self.name = name
26 self.help = help_text
27 if run:
28 self.do_run = run
30 def run(self, *args):
31 log("%s.run: calling %s%s", self, self.do_run, args)
32 return self.do_run(*args)
34 def do_run(self, *args):
35 raise NotImplementedError("control command %s undefined!" % self.name)
37 def raise_error(self, msg):
38 raise ControlError(msg, self.help)
40 def __repr__(self):
41 return "ControlCommand(%s)" % self.name
44class ArgsControlCommand(ControlCommand):
45 """ Adds very basic argument validation """
46 def __init__(self, name, help_text=None, run=None, validation=(), min_args=None, max_args=None):
47 super().__init__(name, help_text, run)
48 self.validation = validation
49 self.min_args = min_args
50 self.max_args = max_args
52 def run(self, *args):
53 if self.min_args is not None and len(args)<self.min_args:
54 self.raise_error("at least %i argument%s required" % (self.min_args, engs(self.min_args)))
55 if self.max_args is not None and len(args)>self.max_args:
56 self.raise_error("too many arguments, %i maximum" % self.max_args)
57 args = list(args)
58 for i,validation in enumerate(self.validation):
59 if i>=len(args):
60 #argument not supplied
61 continue
62 v = args[i]
63 log("running '%s' validation for argument %i: %s (value=%s, type=%s)", self.name, i, validation, v, type(v))
64 if not validation:
65 continue
66 try:
67 args[i] = validation(v)
68 except ValueError as e:
69 self.raise_error("argument %i failed validation: %s" % (i+1, e))
70 return super().run(*args)
72 def do_run(self):
73 raise NotImplementedError()
76class FixedMessageCommand(ControlCommand):
77 """ A control command that returns a fixed message """
78 def __init__(self, name, message, help_text=None):
79 super().__init__(name, help_text)
80 self.message = message
82 def run(self, *_args):
83 return self.message
86class HelloCommand(FixedMessageCommand):
87 """ Just says hello """
89 def __init__(self):
90 super().__init__("hello", "hello", "just says hello back")
93class HelpCommand(ArgsControlCommand):
94 """ The help command looks at the 'help' definition of other commands """
95 def __init__(self, control_commands):
96 super().__init__("help", max_args=1)
97 self.control_commands = control_commands
99 def run(self, *args):
100 if len(args)==0:
101 return "control supports: %s" % csv(self.control_commands)
102 name = args[0]
103 command = self.control_commands.get(name)
104 if not command:
105 self.raise_error("unknown command '%s'" % name)
106 if not command.help:
107 return "sorry, no help message available for '%s'" % name
108 return "control command '%s': %s" % (name, command.help)
111class DebugControl(ArgsControlCommand):
112 def __init__(self):
113 super().__init__("debug",
114 "usage: 'debug enable category', 'debug disable category', 'debug status' or 'debug mark'",
115 min_args=1)
117 def run(self, *args):
118 if len(args)==1 and args[0]=="status":
119 from xpra.log import get_all_loggers
120 return "logging is enabled for: %s" % str(list([str(x) for x in get_all_loggers() if x.is_debug_enabled()]))
121 log_cmd = args[0]
122 if log_cmd=="mark":
123 for _ in range(10):
124 log.info("*"*80)
125 if len(args)>1:
126 log.info("mark: %s", " ".join(args[1:]))
127 else:
128 log.info("mark")
129 for _ in range(10):
130 log.info("*"*80)
131 return "mark inserted into logfile"
132 if len(args)<2:
133 self.raise_error("not enough arguments")
134 if log_cmd not in ("enable", "disable"):
135 self.raise_error("only 'enable' and 'disable' verbs are supported")
136 from xpra.log import add_debug_category, add_disabled_category, enable_debug_for, disable_debug_for
137 #each argument is a group
138 loggers = []
139 groups = args[1:]
140 for group in groups:
141 #and each group is a list of categories
142 #preferably separated by "+",
143 #but we support "," for backwards compatibility:
144 categories = [v.strip() for v in group.replace("+", ",").split(",")]
145 if log_cmd=="enable":
146 add_debug_category(*categories)
147 loggers += enable_debug_for(*categories)
148 else:
149 assert log_cmd=="disable"
150 add_disabled_category(*categories)
151 loggers += disable_debug_for(*categories)
152 if not loggers:
153 log.info("%s debugging, no new loggers matching: %s", log_cmd, csv(groups))
154 else:
155 log.info("%sd debugging for:", log_cmd)
156 for l in loggers:
157 log.info(" - %s", l)
158 return "logging %sd for %s" % (log_cmd, csv(loggers))