File: xdg-open

package info (click to toggle)
xpra 3.1.5%2Bdfsg1-0.2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 18,692 kB
  • sloc: python: 117,045; javascript: 94,780; ansic: 2,843; sh: 939; cpp: 268; makefile: 212; xml: 89
file content (103 lines) | stat: -rwxr-xr-x 3,890 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#!/usr/bin/env python
# This file is part of Xpra.
# Copyright (C) 2017-2020 Antoine Martin <antoine@xpra.org>
# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
# later version. See the file COPYING for details.

import os
import sys


if os.environ.get("XPRA_XDG_OPEN"):
    sys.stderr.write("xdg-open: aborting to avoid forwarding loop\n")
    sys.exit(1)

socket_path = os.environ.get("XPRA_SERVER_SOCKET")
display = os.environ.get("DISPLAY", "unknown")
if socket_path and os.path.exists(socket_path):
    if len(sys.argv)!=2:
        sys.stderr.write("xdg-open: invalid number of arguments\n")
        sys.stderr.write("Try `xdg-open --help' for more information.\n")
    arg = sys.argv[1]
    if arg in ("--help", "--manual"):
        sys.stderr.write("xdg-open { file | URL }\n")
        sys.stderr.flush()
        sys.exit(0)
    if arg=="--version":
        from xpra import __version__
        sys.stdout.write("xpra xdg-open %s\n" % __version__)
        sys.exit(0)

    def send_control_command(*control_command_args):
        from subprocess import Popen, PIPE
        try:
            command = ["xpra", "control", "socket://%s" % socket_path] + list(control_command_args)
            proc = Popen(command, stdout=PIPE, stderr=PIPE)
            #sys.stderr.write("Popen(%s)=%s\n" % (command, proc))
            out, err = proc.communicate(None)
            if proc.returncode==0:
                sys.exit(0)
            else:
                if out:
                    try:
                        sys.stdout.buffer.write(out)
                    except AttributeError:
                        sys.stdout.write(out)
                    sys.stdout.flush()
                if err:
                    try:
                        sys.stderr.buffer.write(err)
                    except AttributeError:
                        sys.stderr.write(err)
                    sys.stderr.flush()
        except Exception as e:
            sys.stderr.write("xdg-open: failed to forward to xpra server using socket '%s': %s\n" % (socket_path, e))
            sys.stderr.flush()
        sys.exit(1)

    #try to forward URI or file:
    #sys.stderr.write("xdg-open: forwarding request to xpra server at '%s'\n" % (socket_path,))
    filename = os.path.abspath(arg)
    #sys.stderr.write("arg: '%s'\n" % x)
    if arg.find("://")>0:
        proto, filename = arg.split("://", 1)
        if proto=="file":
            #this is a URL and may be escaped:
            from urllib.parse import unquote
            send_control_command("send-file", unquote(filename), "open", "*")
        else:
            send_control_command("open-url", arg, "*")
    elif os.path.exists(arg) and os.path.isfile(arg):
        send_control_command("send-file", filename, "open", "*")
    elif os.path.exists(arg) and not os.path.isfile(arg):
        #fall-through to regular xdg-open:
        pass
    else:
        sys.stderr.write("xdg-open: unrecognized argument form '%s'\n" % arg)
        sys.exit(1)


#fallback to the "real" xdg-open:
this_file = os.path.abspath(__file__)
xdg_open_override_dir = os.path.dirname(this_file)
env = os.environ.copy()
PATH = env.get("PATH", "").split(os.pathsep)
if xdg_open_override_dir not in ("/usr/bin", "/bin"):
    #remove our path from PATH:
    PATH = [x for x in PATH if os.path.abspath(x)!=xdg_open_override_dir]
    env["PATH"] = os.pathsep.join(PATH)
env["XPRA_XDG_OPEN"] = "1"
#find the real xdg-open:
real_xdg_open = None
for x in PATH:
    real_xdg_open = os.path.join(x, "xdg-open")
    if os.path.exists(real_xdg_open) and os.path.isfile(real_xdg_open):
        break
if not real_xdg_open:
    sys.stderr.write("xdg-open: real executable not found in $PATH\n")
    sys.exit(1)
if real_xdg_open==this_file:
    sys.stderr.write("xdg-open: loop detected\n")
    sys.exit(1)
os.execve(real_xdg_open, ["xdg-open"]+sys.argv[1:], env)