1# -*- coding: utf-8 -*-
2# This file is part of Xpra.
3# Copyright (C) 2010-2021 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.
6
7from xpra.util import std, typedict, net_utf8
8from xpra.server.source.stub_source_mixin import StubSourceMixin
9from xpra.os_util import platform_name
10from xpra.log import Logger
11
12log = Logger("server")
13
14
15class ClientInfoMixin(StubSourceMixin):
16    """
17    Store information about the client.
18    """
19
20    def cleanup(self):
21        self.init_state()
22
23    def init_state(self):
24        self.uuid = ""
25        self.session_id = ""
26        self.machine_id = ""
27        self.hostname = ""
28        self.username = ""
29        self.user = ""
30        self.name = ""
31        self.argv = ()
32        self.sharing = False
33        # client capabilities/options:
34        self.client_setting_change = False
35        self.client_type = None
36        self.client_version = None
37        self.client_revision= None
38        self.client_bits = 0
39        self.client_platform = None
40        self.client_machine = None
41        self.client_processor = None
42        self.client_release = None
43        self.client_linux_distribution = None
44        self.client_proxy = False
45        self.client_wm_name = None
46        self.client_session_type = None
47        self.client_session_type_full = None
48        self.client_connection_data = {}
49        self.client_opengl = {}
50        self.proxy_hostname = None
51        self.proxy_platform = None
52        self.proxy_release = None
53        self.proxy_version = None
54        self.proxy_version = None
55
56    def parse_client_caps(self, c : typedict):
57        self.uuid = c.strget("uuid")
58        self.session_id = c.strget("session-id")
59        self.machine_id = c.strget("machine_id")
60        self.hostname = c.strget("hostname")
61        self.username = c.strget("username")
62        self.user = c.strget("user")
63        self.name = c.strget("name")
64        self.argv = c.strtupleget("argv")
65        self.sharing = c.boolget("share")
66        self.client_type = c.strget("client_type", "PyGTK")
67        self.client_platform = c.strget("platform")
68        self.client_machine = c.strget("platform.machine")
69        self.client_processor = c.strget("platform.processor")
70        self.client_release = c.strget("platform.sysrelease")
71        self.client_linux_distribution = c.strtupleget("platform.linux_distribution")
72        self.client_version = c.strget("version")
73        self.client_revision = c.strget("build.revision")
74        self.client_bits = c.intget("python.bits")
75        self.client_proxy = c.boolget("proxy")
76        self.client_wm_name = c.conv_get("wm_name", "", net_utf8)
77        self.client_session_type = c.strget("session-type")
78        self.client_session_type_full = c.strget("session-type.full", "")
79        self.client_setting_change = c.boolget("setting-change")
80        self.client_opengl = typedict(c.dictget("opengl") or {})
81        self.proxy_hostname = c.strget("proxy.hostname")
82        self.proxy_platform = c.strget("proxy.platform")
83        self.proxy_release = c.strget("proxy.platform.sysrelease")
84        self.proxy_version = c.strget("proxy.version")
85        self.proxy_version = c.strget("proxy.build.version", self.proxy_version)
86        log("client uuid %s", self.uuid)
87
88    def get_connect_info(self) -> list:
89        cinfo = []
90        #client platform / version info:
91        pinfo = ""
92        if self.client_platform:
93            pinfo = " %s" % platform_name(self.client_platform, self.client_linux_distribution or self.client_release)
94        if self.client_session_type:
95            pinfo += " %s" % self.client_session_type
96        revinfo = ""
97        if self.client_revision:
98            revinfo="-r%s" % self.client_revision
99        bitsstr = ""
100        if self.client_bits:
101            bitsstr = " %i-bit" % self.client_bits
102        cinfo.append("%s%s client version %s%s%s" % (
103            std(self.client_type), pinfo, std(self.client_version), std(revinfo), bitsstr)
104        )
105        #opengl info:
106        if self.client_opengl:
107            msg = "OpenGL is "
108            if not self.client_opengl.boolget("enabled"):
109                msg += "disabled"
110            else:
111                msg += "enabled"
112                driver_info = self.client_opengl.strget("renderer") or self.client_opengl.strget("vendor")
113                if driver_info:
114                    msg += " with %s" % driver_info
115            cinfo.append(msg)
116        #connection info:
117        msg = ""
118        if self.hostname:
119            msg += "connected from '%s'" % std(self.hostname)
120        if self.username:
121            msg += " as '%s'" % std(self.username)
122            if self.name and self.name!=self.username:
123                msg += " - '%s'" % std(self.name)
124        if msg:
125            cinfo.append(msg)
126        #proxy info
127        if self.client_proxy:
128            msg = "via %s proxy version %s" % (
129                platform_name(self.proxy_platform, self.proxy_release),
130                std(self.proxy_version or "unknown")
131                )
132            if self.proxy_hostname:
133                msg += " on '%s'" % std(self.proxy_hostname)
134            cinfo.append(msg)
135        return cinfo
136
137
138    def get_info(self) -> dict:
139        info = {
140                "version"           : self.client_version or "unknown",
141                "revision"          : self.client_revision or "unknown",
142                "platform_name"     : platform_name(self.client_platform, self.client_release),
143                "session-type"      : self.client_session_type or "",
144                "session-type.full" : self.client_session_type_full or "",
145                "session-id"        : self.session_id or "",
146                "uuid"              : self.uuid or "",
147                "hostname"          : self.hostname or "",
148                "user"              : self.user,
149                "name"              : self.name,
150                "argv"              : self.argv or (),
151                "sharing"           : bool(self.sharing),
152                }
153
154        def addattr(k, name):
155            v = getattr(self, name)
156            if v is not None:
157                info[k] = v
158        for x in ("type", "platform", "release", "machine", "processor", "proxy", "wm_name", "session_type"):
159            addattr(x, "client_"+x)
160        return info
161