View | Details | Raw Unified | Return to bug 55948
Collapse All | Expand All

(-)a/gpupdate/gpoa/gpt/shortcuts.py (-3 / +41 lines)
Lines 23-32 Link Here
23
from xdg.DesktopEntry import DesktopEntry
23
from xdg.DesktopEntry import DesktopEntry
24
import json
24
import json
25
25
26
from util.windows import transform_windows_path
26
from util.windows import (
27
    transform_windows_path,
28
    expand_windows_var
29
)
27
from util.xml import get_xml_root
30
from util.xml import get_xml_root
28
from util.paths import get_desktop_files_directory
31
from util.paths import get_desktop_files_directory
29
from .dynamic_attributes import DynamicAttributes
32
from .dynamic_attributes import DynamicAttributes
33
import os
34
import shlex
30
35
31
class TargetType(Enum):
36
class TargetType(Enum):
32
    FILESYSTEM = 'FILESYSTEM'
37
    FILESYSTEM = 'FILESYSTEM'
Lines 71-93 Link Here
71
    '''
76
    '''
72
    shortcuts = list()
77
    shortcuts = list()
73
78
79
    def looks_like_url(p):
80
        if not p:
81
            return False
82
        lower = p.lower()
83
        return lower.startswith('http://') or lower.startswith('https://') or lower.startswith('ftp://') or lower.startswith('file://') #or lower.startswith('smb://')
84
74
    for link in get_xml_root(shortcuts_file):
85
    for link in get_xml_root(shortcuts_file):
75
        props = link.find('Properties')
86
        props = link.find('Properties')
76
        # Location of the link itself
87
        # Location of the link itself
77
        dest = props.get('shortcutPath')
88
        dest = props.get('shortcutPath')
78
        # Location where link should follow
89
        # Location where link should follow
79
        path = transform_windows_path(props.get('targetPath'))
90
        path = transform_windows_path(props.get('targetPath'))
91
        path = expand_windows_var(path)
92
        # Location icon
93
        path_icon = transform_windows_path(props.get('iconPath'))
94
        path_icon = expand_windows_var(path_icon)
95
        if path_icon.startswith('//'):
96
                path_icon = f'{shlex.quote("smb://" + path_icon.lstrip("/"))}'
80
        # Arguments to executable file
97
        # Arguments to executable file
81
        arguments = props.get('arguments')
98
        arguments = props.get('arguments')
82
        # URL or FILESYSTEM
99
        # URL or FILESYSTEM
83
        target_type = get_ttype(props.get('targetType'))
100
        target_type = get_ttype(props.get('targetType'))
84
101
85
        sc = shortcut(dest, path, arguments, link.get('name'), props.get('action'), target_type)
102
        # Decide Exec behavior:
103
        # - If target is a URL (starts with sheme://) or target_type != FILESYSTEM -> yse xdg-open
104
        # - If target is a filesystem path but not executable -> yse xdg-open
105
        exec_cmd = path # default: run path directly
106
107
        if path:
108
            # If URL-like -> use xdg-open
109
            if path.startswith('//'):
110
                exec_cmd = f'{shlex.quote("smb://" + path.lstrip("/"))}'
111
            elif looks_like_url(path):
112
                exec_cmd = f'xdg-open {shlex.quote(path)}'
113
            else:
114
                # For filesystemc targets: if not executable, use xdg-open
115
                try:
116
                    # os.access needs a real filesystem path; ignore if it's not absolute/exists
117
                    if os.path.isabs(path) and os.path.exists(path):
118
                        if not os.access(path, os.X_OK):
119
                            exec_cmd = f'xdg-open {shlex.quote(path)}'
120
                except Exception:
121
                    pass
122
123
        sc = shortcut(dest, exec_cmd, arguments, link.get('name'), props.get('action'), target_type)
86
        sc.set_changed(link.get('changed'))
124
        sc.set_changed(link.get('changed'))
87
        sc.set_clsid(link.get('clsid'))
125
        sc.set_clsid(link.get('clsid'))
88
        sc.set_guid(link.get('uid'))
126
        sc.set_guid(link.get('uid'))
89
        sc.set_usercontext(link.get('userContext', False))
127
        sc.set_usercontext(link.get('userContext', False))
90
        sc.set_icon(props.get('iconPath'))
128
        sc.set_icon(path_icon)
91
        if props.get('comment'):
129
        if props.get('comment'):
92
            sc.set_comment(props.get('comment'))
130
            sc.set_comment(props.get('comment'))
93
131

Return to bug 55948