From b6b2e5bb03c485bf6c82aa420d60f9a20d0bdd03 Mon Sep 17 00:00:00 2001 From: HelioGuilherme66 Date: Sun, 15 Sep 2024 19:12:37 +0100 Subject: [PATCH] Add Hatch configuration. Command line arguments are not working, i.e. ride --version --- pyproject.toml | 95 ++++++ src/robotide/application/updatenotifier.py | 2 +- src/robotide/postinstall/__init__.py | 340 +++++++++++++++++++ src/robotide/postinstall/__main__.py | 344 +------------------- src/robotide/postinstall/desktopshortcut.py | 5 +- uv.lock | 150 +++++++++ 6 files changed, 595 insertions(+), 341 deletions(-) create mode 100644 pyproject.toml create mode 100644 uv.lock diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 000000000..d0422ec1c --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,95 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "robotframework-ride" +dynamic = ["version"] +description = "RIDE :: Robot Framework Test Data Editor" +license = "Apache-2.0" +license-files = { paths = ["LICENSE.txt"] } +requires-python = ">=3.8, <3.13" +authors = [ + { name = "Robot Framework Developers", email = "robotframework@gmail.com" }, +] +maintainers = [ + { name = "Hélio Guilherme", email = "helioxentric@gmail.com" }, +] +keywords = [ + "robotframework", + "testautomation", + "testing", + "test editor", + "IDE", +] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "License :: OSI Approved :: Apache Software License", + "Operating System :: OS Independent", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Topic :: Software Development :: Testing", +] +dependencies = [ + "psutil", + "Pygments", + "PyPubSub", + "Pywin32; platform_system == 'Windows'", + "wxPython", +] + +[project.urls] +Download = "https://pypi.python.org/pypi/robotframework-ride" +Homepage = "https://github.com/robotframework/RIDE/" + +[tool.hatch.version] +path = "src/robotide/version.py" + +[tool.hatch.build.targets.sdist] +include = [ + "/src", +] +[tool.hatch.build.targets.wheel] +packages = ["src/robotide"] + +[project.scripts] +ride_postinstall = "robotide.postinstall:main" + +[project.gui-scripts] +ride = "robotide:main" + +[tool.hatch.envs.test] +dependencies = [ + "pytest", + "coverage", +] + +[[tool.hatch.envs.test.matrix]] +python = ["3.12"] +version = ["2.1b1"] + +[tool.poetry] +name = "robotframework-ride" +version = "2.1b1" +description = "RIDE :: Robot Framework Test Data Editor" +authors = ["Robot Framework Developers "] +license = "Apache-2.0 license" +readme = "README.adoc" +packages = [{include = "robotide"}] + +[tool.poetry.dependencies] +python = "^3.8" +wxPython = "^4.0.1" +pywin32 = { version = "*", markers = "sys_platform == 'win32'" } +pygments = "*" +robotframework = "*" +pypubsub = "*" +psutil = "*" + +[tool.poetry.group.test.dependencies] +pytest = "*" +pytest-mock = "*" +coverage = "*" diff --git a/src/robotide/application/updatenotifier.py b/src/robotide/application/updatenotifier.py index e5bdb3d9f..e4e84a3ad 100644 --- a/src/robotide/application/updatenotifier.py +++ b/src/robotide/application/updatenotifier.py @@ -30,7 +30,7 @@ from .. import version from ..utils.versioncomparator import cmp_versions, parse_version from ..widgets import ButtonWithHandler, HtmlWindow, RIDEDialog -from ..postinstall.__main__ import MessageDialog +from ..postinstall import MessageDialog _ = wx.GetTranslation # To keep linter/code analyser happy builtins.__dict__['_'] = wx.GetTranslation diff --git a/src/robotide/postinstall/__init__.py b/src/robotide/postinstall/__init__.py index 2735283ee..ac00916d1 100644 --- a/src/robotide/postinstall/__init__.py +++ b/src/robotide/postinstall/__init__.py @@ -13,4 +13,344 @@ # See the License for the specific language governing permissions and # limitations under the License. +import sys +try: + import wx + from wx import Colour +except ImportError: + sys.stderr.write("No wxPython installation detected!" + "\n" + "Please ensure that you have wxPython installed " + "before running RIDE. " + "You can obtain wxPython from " + "https://wxpython.org/pages/downloads/\n" + "or pip install wxPython") + exit(-1) + +from os import environ +from os.path import exists, join +from robotide.widgets import RIDEDialog from .desktopshortcut import ShortcutPlugin + +__doc__ = """ +Usage: python ride_postinstall.py [options] <-install|-remove> + or python -m robotide.postinstall [options] <-install|-remove> + -install - Installs a Desktop Shortcut to RIDE. + -remove - [TODO] Removes a Desktop Shortcut to RIDE. + options: -q - Quiet, don't ask user for confirmation. + -f - Force action. + -help - This help. +""".strip() +# DEBUG: Add -remove, to remove desktop shortcut + +ROBOT_ICO = "robot.ico" +DEFAULT_LANGUAGE = environ.get('LANG', '').split(':') + + +def verify_install(): + try: + from wx import version + except ImportError: + sys.stderr.write("No wxPython installation detected!" + "\n" + "Please ensure that you have wxPython installed " + "before running RIDE. " + "You can obtain wxPython from " + "https://wxpython.org/pages/downloads/\n" + "or pip install wxPython") + return False + else: + sys.stderr.write("wxPython is installed.\n%s\n" % version()) + return True + + +class MessageDialog(RIDEDialog): + def __init__(self, parent, message, title, ttl=10, no_default=False): + RIDEDialog.__init__(self, title=title, parent=parent, size=(300, 200)) + + self.CenterOnScreen(wx.BOTH) + self.timeToLive = ttl + st_msg = [] + for msg in message.split('\n'): + st_msg.append(wx.StaticText(self, -1, msg)) + self.settimetolivemsg = wx.StaticText(self, -1, 'Closing this dialog box in %ds...' % self.timeToLive) + vbox = wx.BoxSizer(wx.VERTICAL) + for sp_msg in st_msg: + vbox.Add(sp_msg, 0, wx.ALIGN_LEFT | wx.TOP, 10) + vbox.Add(self.settimetolivemsg, 0, wx.ALIGN_CENTER | wx.TOP, 10) + self.SetSizer(vbox) + self.SetAffirmativeId(wx.ID_OK) + self._create_buttons(None, no_default) + self.SetBackgroundColour(Colour(self.color_background)) + self.SetForegroundColour(Colour(self.color_foreground)) + self.timer = wx.Timer(self) + self.timer.Start(1000) # Generate a timer event every second + self.Bind(wx.EVT_CLOSE, self.on_close) + self.Bind(wx.EVT_TIMER, self.on_timer, self.timer) + self.Bind(wx.EVT_BUTTON, self.on_cancel, id=wx.ID_CANCEL) + self.Bind(wx.EVT_BUTTON, self.on_no, id=wx.ID_NO) + self.Bind(wx.EVT_CHAR_HOOK, self.on_key_pressed) + + def on_key_pressed(self, event): + key_code = event.GetKeyCode() + if key_code == wx.WXK_ESCAPE: + self.EndModal(wx.ID_NO) + event.Skip() + + def on_cancel(self, evt): + _ = evt + self.EndModal(wx.ID_NO) + + def on_close(self, evt): + self.on_cancel(evt) + + def on_no(self, evt): + self.on_cancel(evt) + + def on_timer(self, evt): + _ = evt + self.timeToLive -= 1 + self.settimetolivemsg.SetLabel('Closing this dialog box in %ds...' % self.timeToLive) + + if self.timeToLive == 0: + self.timer.Stop() + self.EndModal(wx.ID_NO) + + def _create_buttons(self, sizer, no_default=False): + flags = wx.OK | wx.CANCEL + if no_default: + flags |= wx.NO_DEFAULT + buttons = self.CreateStdDialogButtonSizer(flags) + self.SetBackgroundColour(Colour(self.color_background)) + self.SetForegroundColour(Colour(self.color_foreground)) + for item in self.GetChildren(): + if isinstance(item, (wx.Button, wx.BitmapButton)): + item.SetBackgroundColour(Colour(self.color_secondary_background)) + item.SetOwnBackgroundColour(Colour(self.color_secondary_background)) + item.SetForegroundColour(Colour(self.color_secondary_foreground)) + item.SetOwnForegroundColour(Colour(self.color_secondary_foreground)) + self.Sizer.Add(buttons, flag=wx.ALIGN_CENTER | wx.ALL, border=5) + + +def _askyesno(title, message, frame=None, no_default=False): + if frame is None: + _ = wx.App() + parent = wx.Frame(None, size=(0, 0)) + else: + parent = wx.Frame(frame, size=(0, 0)) + parent.CenterOnScreen() + dlg = MessageDialog(parent, message, title, ttl=8, no_default=no_default) + dlg.Fit() + result = dlg.ShowModal() in [wx.ID_YES, wx.ID_OK] + print("Result %s" % result) + if dlg: + dlg.Destroy() + parent.Destroy() + return result + + +def _askdirectory(title, initialdir, frame=None): + import wx + if frame is None: + _ = wx.App() + parent = wx.Frame(None, size=(0, 0)) + else: + parent = wx.Frame(frame, size=(0, 0)) + parent.CenterOnScreen() + dlg = wx.DirDialog(parent, title, initialdir, style=wx.DD_DIR_MUST_EXIST) + if dlg.ShowModal() == wx.ID_OK: + result = dlg.GetPath() + else: + result = None + dlg.Destroy() + parent.Destroy() + return result + + +def _create_desktop_shortcut_linux(frame=None): + from os.path import expanduser + from os import chmod, chown + from stat import S_IRWXU + import subprocess + import pwd + import sysconfig + # DEBUG: Add more languages + desktop = {"de": "Desktop", "en": "Desktop", "es": "Escritorio", + "fi": r"Työpöytä", "fr": "Bureau", "it": "Scrivania", + "pt": r"Área de Trabalho"} + user = str(subprocess.check_output(['logname']).strip(), encoding='utf-8') + try: + ndesktop = desktop[DEFAULT_LANGUAGE[0][:2]] + directory = join("/home", user, ndesktop) + defaultdir = join("/home", user, "Desktop") + if not exists(directory): + if exists(defaultdir): + directory = defaultdir + else: + if not option_q: + directory = _askdirectory(title="Locate Desktop Directory", + initialdir=join(expanduser('~')), + frame=frame) + else: + directory = None + except KeyError: + if not option_q: + directory = _askdirectory(title="Locate Desktop Directory", + initialdir=join(expanduser('~')), + frame=frame) + else: + directory = None + if directory is None: + sys.stderr.write("Desktop shortcut creation aborted!\n") + return False + try: + link = join(directory, "RIDE.desktop") + except UnicodeError: + link = join(directory.encode('utf-8'), "RIDE.desktop") + if not exists(link) or option_f: + if not option_q and not option_f: + if not _askyesno("Setup", "Create desktop shortcut?", frame): + return False + roboticon = join(sysconfig.get_paths()["purelib"], "robotide", "widgets", ROBOT_ICO) + if not exists(roboticon): + try: + import robotide as _ + roboticon = join(_.__path__[0], "widgets", ROBOT_ICO) + except ImportError: + _ = None + if not exists(roboticon): + roboticon = join("FIXME: find correct path to: .../site-packages/", "robotide", "widgets", ROBOT_ICO) + with open(link, "w+") as shortcut: + shortcut.write(f"#!/usr/bin/env xdg-open\n[Desktop Entry]\n" + f"Exec={sys.executable} -m robotide.__init__\n" + f"Comment=A Robot Framework IDE\nGenericName=RIDE\n" + f"Icon={roboticon}\n" + f"Name=RIDE\nStartupNotify=true\nTerminal=false\n" + "Type=Application\nX-KDE-SubstituteUID=false\n") + uid = pwd.getpwnam(user).pw_uid + chown(link, uid, -1) # groupid == -1 means keep unchanged + chmod(link, S_IRWXU) + + +def _create_desktop_shortcut_mac(frame=None): + import os + import shutil + import subprocess + ride_app_name = 'RIDE.app' + application_path = '/Applications' + ride_app_pc_path = os.path.join(application_path, ride_app_name) + ride_app_module_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), ride_app_name) + + if not exists(ride_app_pc_path) or option_f: + if not option_q and not option_f and not _askyesno("Setup", "Create application shortcut?", frame): + return False + app_script = os.path.join(ride_app_module_path, 'Contents', 'MacOS', 'RIDE') + with open(app_script, 'w+') as shortcut: + shortcut.write("#!/bin/sh\nPAL=$PATH\nfor i in `cat /etc/paths`\n do\n PAL=\"$PAL:$i\"\n" + " done\nPATH=$PAL\nexport $PATH\n{} -m robotide.__init__ $* 2>" + " /dev/null &\n".format(sys.executable)) + if exists(ride_app_pc_path): + shutil.rmtree(ride_app_pc_path, True) + shutil.copytree(ride_app_module_path, ride_app_pc_path) + user = str(subprocess.check_output(['logname']).strip(), encoding='utf-8') + user_desktop_link = '/Users/' + user + '/Desktop/' + ride_app_name + if exists(user_desktop_link): + os.remove(user_desktop_link) + try: + os.symlink(ride_app_pc_path, user_desktop_link) + except Exception as e: + print(e) + + +def _create_desktop_shortcut_windows(frame=None): + # Dependency of http://sourceforge.net/projects/pywin32/ + import os + import sys + try: + from win32com.shell import shell, shellcon + except ImportError: + sys.stderr.write("Cannot create desktop shortcut.\nPlease install" + " pywin32 from https://github.com/mhammond/pywin32\n" + "or pip install pywin32") + return False + desktop = shell.SHGetFolderPath(0, shellcon.CSIDL_DESKTOP, None, 0) + link = os.path.join(desktop, 'RIDE.lnk') + public_link = os.path.join(os.getenv('PUBLIC'), 'Desktop', 'RIDE.lnk') + icon = os.path.join(sys.prefix, 'Lib', 'site-packages', 'robotide', + 'widgets', 'robot.ico') + if not (exists(public_link) or exists(link)) or option_f: + if not option_q and not option_f: + if not _askyesno("Setup", "Create desktop shortcut?", frame): + sys.stderr.write("Users can create a Desktop shortcut to RIDE " + "with:\n%s -m robotide.postinstall -install\n" + % sys.executable) + return False + import pythoncom + shortcut = pythoncom.CoCreateInstance(shell.CLSID_ShellLink, None, + pythoncom.CLSCTX_INPROC_SERVER, + shell.IID_IShellLink) + command_args = " -c \"from robotide import main; main()\"" + shortcut.SetPath(sys.executable.replace('python.exe', 'pythonw.exe')) + shortcut.SetArguments(command_args) + shortcut.SetDescription("Robot Framework testdata editor") + shortcut.SetIconLocation(icon, 0) + persist_file = shortcut.QueryInterface(pythoncom.IID_IPersistFile) + from pywintypes import com_error + try: + persist_file.Save(public_link, 0) + sys.stderr.write("Desktop shortcut created for all users.") + except com_error: + persist_file.Save(link, 0) + + +def create_desktop_shortcut(platform, frame=None): + if platform.startswith("linux"): + return _create_desktop_shortcut_linux(frame) + elif platform.startswith("darwin"): + return _create_desktop_shortcut_mac(frame) + elif platform.startswith("win"): + return _create_desktop_shortcut_windows(frame) + else: + sys.stderr.write("Unknown platform {0}: Failed to create desktop short" + "cut.".format(platform)) + return False + + +def caller(frame, platform): + # Options + global option_q + global option_f + option_q = None + option_f = frame is not None + # We don't verify install because called from RIDE + return create_desktop_shortcut(platform, frame) + + +def main(*args): + # Options + global option_q + global option_f + option_q = option_f = None + option_q = next((x for x in args if x == "-q"), None) + if option_q is not None: + del args[args.index(option_q)] + option_q = True + option_f = next((x for x in args if x == "-f"), None) + if option_f is not None: + del args[args.index(option_f)] + option_f = True + arg = args[-1] if len(args) == 1 and args[-1] in ['-install', '-remove', + '-help'] else None + if arg == '-install': + platform = sys.platform.lower() + doit = verify_install() + if doit: + create_desktop_shortcut(platform) + elif arg == '-remove': + sys.stderr.write("Sorry, -remove is not implemented yet.\n") + else: + sys.stderr.write(__doc__) + sys.stderr.write("\n") + +if __name__ == '__main__': + main(*sys.argv[1:]) \ No newline at end of file diff --git a/src/robotide/postinstall/__main__.py b/src/robotide/postinstall/__main__.py index 0672e77e2..afea591b8 100755 --- a/src/robotide/postinstall/__main__.py +++ b/src/robotide/postinstall/__main__.py @@ -15,345 +15,13 @@ # See the License for the specific language governing permissions and # limitations under the License. - import sys -try: - import wx - from wx import Colour -except ImportError: - sys.stderr.write("No wxPython installation detected!" - "\n" - "Please ensure that you have wxPython installed " - "before running RIDE. " - "You can obtain wxPython from " - "https://wxpython.org/pages/downloads/\n" - "or pip install wxPython") - exit(-1) - -from os import environ -from os.path import exists, join -from robotide.widgets import RIDEDialog - -__doc__ = """ -Usage: python ride_postinstall.py [options] <-install|-remove> - or python -m robotide.postinstall [options] <-install|-remove> - -install - Installs a Desktop Shortcut to RIDE. - -remove - [TODO] Removes a Desktop Shortcut to RIDE. - options: -q - Quiet, don't ask user for confirmation. - -f - Force action. - -help - This help. -""".strip() -# DEBUG: Add -remove, to remove desktop shortcut - -ROBOT_ICO = "robot.ico" -DEFAULT_LANGUAGE = environ.get('LANG', '').split(':') - - -def verify_install(): - try: - from wx import version - except ImportError: - sys.stderr.write("No wxPython installation detected!" - "\n" - "Please ensure that you have wxPython installed " - "before running RIDE. " - "You can obtain wxPython from " - "https://wxpython.org/pages/downloads/\n" - "or pip install wxPython") - return False - else: - sys.stderr.write("wxPython is installed.\n%s\n" % version()) - return True - - -class MessageDialog(RIDEDialog): - def __init__(self, parent, message, title, ttl=10, no_default=False): - RIDEDialog.__init__(self, title=title, parent=parent, size=(300, 200)) - - self.CenterOnScreen(wx.BOTH) - self.timeToLive = ttl - st_msg = [] - for msg in message.split('\n'): - st_msg.append(wx.StaticText(self, -1, msg)) - self.settimetolivemsg = wx.StaticText(self, -1, 'Closing this dialog box in %ds...' % self.timeToLive) - vbox = wx.BoxSizer(wx.VERTICAL) - for sp_msg in st_msg: - vbox.Add(sp_msg, 0, wx.ALIGN_LEFT | wx.TOP, 10) - vbox.Add(self.settimetolivemsg, 0, wx.ALIGN_CENTER | wx.TOP, 10) - self.SetSizer(vbox) - self.SetAffirmativeId(wx.ID_OK) - self._create_buttons(None, no_default) - self.SetBackgroundColour(Colour(self.color_background)) - self.SetForegroundColour(Colour(self.color_foreground)) - self.timer = wx.Timer(self) - self.timer.Start(1000) # Generate a timer event every second - self.Bind(wx.EVT_CLOSE, self.on_close) - self.Bind(wx.EVT_TIMER, self.on_timer, self.timer) - self.Bind(wx.EVT_BUTTON, self.on_cancel, id=wx.ID_CANCEL) - self.Bind(wx.EVT_BUTTON, self.on_no, id=wx.ID_NO) - self.Bind(wx.EVT_CHAR_HOOK, self.on_key_pressed) - - def on_key_pressed(self, event): - key_code = event.GetKeyCode() - if key_code == wx.WXK_ESCAPE: - self.EndModal(wx.ID_NO) - event.Skip() - - def on_cancel(self, evt): - _ = evt - self.EndModal(wx.ID_NO) - - def on_close(self, evt): - self.on_cancel(evt) - - def on_no(self, evt): - self.on_cancel(evt) - - def on_timer(self, evt): - _ = evt - self.timeToLive -= 1 - self.settimetolivemsg.SetLabel('Closing this dialog box in %ds...' % self.timeToLive) - - if self.timeToLive == 0: - self.timer.Stop() - self.EndModal(wx.ID_NO) - - def _create_buttons(self, sizer, no_default=False): - flags = wx.OK | wx.CANCEL - if no_default: - flags |= wx.NO_DEFAULT - buttons = self.CreateStdDialogButtonSizer(flags) - self.SetBackgroundColour(Colour(self.color_background)) - self.SetForegroundColour(Colour(self.color_foreground)) - for item in self.GetChildren(): - if isinstance(item, (wx.Button, wx.BitmapButton)): - item.SetBackgroundColour(Colour(self.color_secondary_background)) - item.SetOwnBackgroundColour(Colour(self.color_secondary_background)) - item.SetForegroundColour(Colour(self.color_secondary_foreground)) - item.SetOwnForegroundColour(Colour(self.color_secondary_foreground)) - self.Sizer.Add(buttons, flag=wx.ALIGN_CENTER | wx.ALL, border=5) - - -def _askyesno(title, message, frame=None, no_default=False): - if frame is None: - _ = wx.App() - parent = wx.Frame(None, size=(0, 0)) - else: - parent = wx.Frame(frame, size=(0, 0)) - parent.CenterOnScreen() - dlg = MessageDialog(parent, message, title, ttl=8, no_default=no_default) - dlg.Fit() - result = dlg.ShowModal() in [wx.ID_YES, wx.ID_OK] - print("Result %s" % result) - if dlg: - dlg.Destroy() - parent.Destroy() - return result - - -def _askdirectory(title, initialdir, frame=None): - import wx - if frame is None: - _ = wx.App() - parent = wx.Frame(None, size=(0, 0)) - else: - parent = wx.Frame(frame, size=(0, 0)) - parent.CenterOnScreen() - dlg = wx.DirDialog(parent, title, initialdir, style=wx.DD_DIR_MUST_EXIST) - if dlg.ShowModal() == wx.ID_OK: - result = dlg.GetPath() - else: - result = None - dlg.Destroy() - parent.Destroy() - return result - - -def _create_desktop_shortcut_linux(frame=None): - from os.path import expanduser - from os import chmod, chown - from stat import S_IRWXU - import subprocess - import pwd - import sysconfig - # DEBUG: Add more languages - desktop = {"de": "Desktop", "en": "Desktop", "es": "Escritorio", - "fi": r"Työpöytä", "fr": "Bureau", "it": "Scrivania", - "pt": r"Área de Trabalho"} - user = str(subprocess.check_output(['logname']).strip(), encoding='utf-8') - try: - ndesktop = desktop[DEFAULT_LANGUAGE[0][:2]] - directory = join("/home", user, ndesktop) - defaultdir = join("/home", user, "Desktop") - if not exists(directory): - if exists(defaultdir): - directory = defaultdir - else: - if not option_q: - directory = _askdirectory(title="Locate Desktop Directory", - initialdir=join(expanduser('~')), - frame=frame) - else: - directory = None - except KeyError: - if not option_q: - directory = _askdirectory(title="Locate Desktop Directory", - initialdir=join(expanduser('~')), - frame=frame) - else: - directory = None - if directory is None: - sys.stderr.write("Desktop shortcut creation aborted!\n") - return False - try: - link = join(directory, "RIDE.desktop") - except UnicodeError: - link = join(directory.encode('utf-8'), "RIDE.desktop") - if not exists(link) or option_f: - if not option_q and not option_f: - if not _askyesno("Setup", "Create desktop shortcut?", frame): - return False - roboticon = join(sysconfig.get_paths()["purelib"], "robotide", "widgets", ROBOT_ICO) - if not exists(roboticon): - try: - import robotide as _ - roboticon = join(_.__path__[0], "widgets", ROBOT_ICO) - except ImportError: - _ = None - if not exists(roboticon): - roboticon = join("FIXME: find correct path to: .../site-packages/", "robotide", "widgets", ROBOT_ICO) - with open(link, "w+") as shortcut: - shortcut.write(f"#!/usr/bin/env xdg-open\n[Desktop Entry]\n" - f"Exec={sys.executable} -m robotide.__init__\n" - f"Comment=A Robot Framework IDE\nGenericName=RIDE\n" - f"Icon={roboticon}\n" - f"Name=RIDE\nStartupNotify=true\nTerminal=false\n" - "Type=Application\nX-KDE-SubstituteUID=false\n") - uid = pwd.getpwnam(user).pw_uid - chown(link, uid, -1) # groupid == -1 means keep unchanged - chmod(link, S_IRWXU) - - -def _create_desktop_shortcut_mac(frame=None): - import os - import shutil - import subprocess - ride_app_name = 'RIDE.app' - application_path = '/Applications' - ride_app_pc_path = os.path.join(application_path, ride_app_name) - ride_app_module_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), ride_app_name) - - if not exists(ride_app_pc_path) or option_f: - if not option_q and not option_f and not _askyesno("Setup", "Create application shortcut?", frame): - return False - app_script = os.path.join(ride_app_module_path, 'Contents', 'MacOS', 'RIDE') - with open(app_script, 'w+') as shortcut: - shortcut.write("#!/bin/sh\nPAL=$PATH\nfor i in `cat /etc/paths`\n do\n PAL=\"$PAL:$i\"\n" - " done\nPATH=$PAL\nexport $PATH\n{} -m robotide.__init__ $* 2>" - " /dev/null &\n".format(sys.executable)) - if exists(ride_app_pc_path): - shutil.rmtree(ride_app_pc_path, True) - shutil.copytree(ride_app_module_path, ride_app_pc_path) - user = str(subprocess.check_output(['logname']).strip(), encoding='utf-8') - user_desktop_link = '/Users/' + user + '/Desktop/' + ride_app_name - if exists(user_desktop_link): - os.remove(user_desktop_link) - try: - os.symlink(ride_app_pc_path, user_desktop_link) - except Exception as e: - print(e) - - -def _create_desktop_shortcut_windows(frame=None): - # Dependency of http://sourceforge.net/projects/pywin32/ - import os - import sys - try: - from win32com.shell import shell, shellcon - except ImportError: - sys.stderr.write("Cannot create desktop shortcut.\nPlease install" - " pywin32 from https://github.com/mhammond/pywin32\n" - "or pip install pywin32") - return False - desktop = shell.SHGetFolderPath(0, shellcon.CSIDL_DESKTOP, None, 0) - link = os.path.join(desktop, 'RIDE.lnk') - public_link = os.path.join(os.getenv('PUBLIC'), 'Desktop', 'RIDE.lnk') - icon = os.path.join(sys.prefix, 'Lib', 'site-packages', 'robotide', - 'widgets', 'robot.ico') - if not (exists(public_link) or exists(link)) or option_f: - if not option_q and not option_f: - if not _askyesno("Setup", "Create desktop shortcut?", frame): - sys.stderr.write("Users can create a Desktop shortcut to RIDE " - "with:\n%s -m robotide.postinstall -install\n" - % sys.executable) - return False - import pythoncom - shortcut = pythoncom.CoCreateInstance(shell.CLSID_ShellLink, None, - pythoncom.CLSCTX_INPROC_SERVER, - shell.IID_IShellLink) - command_args = " -c \"from robotide import main; main()\"" - shortcut.SetPath(sys.executable.replace('python.exe', 'pythonw.exe')) - shortcut.SetArguments(command_args) - shortcut.SetDescription("Robot Framework testdata editor") - shortcut.SetIconLocation(icon, 0) - persist_file = shortcut.QueryInterface(pythoncom.IID_IPersistFile) - from pywintypes import com_error - try: - persist_file.Save(public_link, 0) - sys.stderr.write("Desktop shortcut created for all users.") - except com_error: - persist_file.Save(link, 0) - - -def create_desktop_shortcut(platform, frame=None): - if platform.startswith("linux"): - return _create_desktop_shortcut_linux(frame) - elif platform.startswith("darwin"): - return _create_desktop_shortcut_mac(frame) - elif platform.startswith("win"): - return _create_desktop_shortcut_windows(frame) - else: - sys.stderr.write("Unknown platform {0}: Failed to create desktop short" - "cut.".format(platform)) - return False - - -def caller(frame, platform): - # Options - global option_q - global option_f - option_q = None - option_f = frame is not None - # We don't verify install because called from RIDE - return create_desktop_shortcut(platform, frame) - -def main(*args): - # Options - global option_q - global option_f - option_q = option_f = None - option_q = next((x for x in args if x == "-q"), None) - if option_q is not None: - del args[args.index(option_q)] - option_q = True - option_f = next((x for x in args if x == "-f"), None) - if option_f is not None: - del args[args.index(option_f)] - option_f = True - arg = args[-1] if len(args) == 1 and args[-1] in ['-install', '-remove', - '-help'] else None - if arg == '-install': - platform = sys.platform.lower() - doit = verify_install() - if doit: - create_desktop_shortcut(platform) - elif arg == '-remove': - sys.stderr.write("Sorry, -remove is not implemented yet.\n") - else: - sys.stderr.write(__doc__) - sys.stderr.write("\n") +if __name__ == '__main__' and 'robotide' not in sys.modules: + from pathlib import Path + robotide_dir = Path(__file__).absolute().parent # zipsafe + sys.path = [str(robotide_dir.parent)] + [p for p in sys.path if Path(p) != robotide_dir] +from robotide.postinstall import main -if __name__ == '__main__': - main(sys.argv[1:]) +main(*sys.argv[1:]) diff --git a/src/robotide/postinstall/desktopshortcut.py b/src/robotide/postinstall/desktopshortcut.py index 231cddfde..82c02bf29 100644 --- a/src/robotide/postinstall/desktopshortcut.py +++ b/src/robotide/postinstall/desktopshortcut.py @@ -20,7 +20,6 @@ from ..pluginapi import Plugin from ..action import ActionInfo -from ..postinstall import __main__ as postinstall _ = wx.GetTranslation # To keep linter/code analyser happy builtins.__dict__['_'] = wx.GetTranslation @@ -63,4 +62,6 @@ def on_view_shortcut_create(self, event): @staticmethod def call_creator(notebook): - return postinstall.caller(notebook.GetParent(), sys.platform.lower()) + from . import caller + + return caller(notebook.GetParent(), sys.platform.lower()) diff --git a/uv.lock b/uv.lock new file mode 100644 index 000000000..77f44380b --- /dev/null +++ b/uv.lock @@ -0,0 +1,150 @@ +version = 1 +requires-python = ">=3.8, <3.13" + +[[package]] +name = "numpy" +version = "1.24.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a4/9b/027bec52c633f6556dba6b722d9a0befb40498b9ceddd29cbe67a45a127c/numpy-1.24.4.tar.gz", hash = "sha256:80f5e3a4e498641401868df4208b74581206afbee7cf7b8329daae82676d9463", size = 10911229 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6b/80/6cdfb3e275d95155a34659163b83c09e3a3ff9f1456880bec6cc63d71083/numpy-1.24.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c0bfb52d2169d58c1cdb8cc1f16989101639b34c7d3ce60ed70b19c63eba0b64", size = 19789140 }, + { url = "https://files.pythonhosted.org/packages/64/5f/3f01d753e2175cfade1013eea08db99ba1ee4bdb147ebcf3623b75d12aa7/numpy-1.24.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ed094d4f0c177b1b8e7aa9cba7d6ceed51c0e569a5318ac0ca9a090680a6a1b1", size = 13854297 }, + { url = "https://files.pythonhosted.org/packages/5a/b3/2f9c21d799fa07053ffa151faccdceeb69beec5a010576b8991f614021f7/numpy-1.24.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79fc682a374c4a8ed08b331bef9c5f582585d1048fa6d80bc6c35bc384eee9b4", size = 13995611 }, + { url = "https://files.pythonhosted.org/packages/10/be/ae5bf4737cb79ba437879915791f6f26d92583c738d7d960ad94e5c36adf/numpy-1.24.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ffe43c74893dbf38c2b0a1f5428760a1a9c98285553c89e12d70a96a7f3a4d6", size = 17282357 }, + { url = "https://files.pythonhosted.org/packages/c0/64/908c1087be6285f40e4b3e79454552a701664a079321cff519d8c7051d06/numpy-1.24.4-cp310-cp310-win32.whl", hash = "sha256:4c21decb6ea94057331e111a5bed9a79d335658c27ce2adb580fb4d54f2ad9bc", size = 12429222 }, + { url = "https://files.pythonhosted.org/packages/22/55/3d5a7c1142e0d9329ad27cece17933b0e2ab4e54ddc5c1861fbfeb3f7693/numpy-1.24.4-cp310-cp310-win_amd64.whl", hash = "sha256:b4bea75e47d9586d31e892a7401f76e909712a0fd510f58f5337bea9572c571e", size = 14841514 }, + { url = "https://files.pythonhosted.org/packages/a9/cc/5ed2280a27e5dab12994c884f1f4d8c3bd4d885d02ae9e52a9d213a6a5e2/numpy-1.24.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f136bab9c2cfd8da131132c2cf6cc27331dd6fae65f95f69dcd4ae3c3639c810", size = 19775508 }, + { url = "https://files.pythonhosted.org/packages/c0/bc/77635c657a3668cf652806210b8662e1aff84b818a55ba88257abf6637a8/numpy-1.24.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e2926dac25b313635e4d6cf4dc4e51c8c0ebfed60b801c799ffc4c32bf3d1254", size = 13840033 }, + { url = "https://files.pythonhosted.org/packages/a7/4c/96cdaa34f54c05e97c1c50f39f98d608f96f0677a6589e64e53104e22904/numpy-1.24.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:222e40d0e2548690405b0b3c7b21d1169117391c2e82c378467ef9ab4c8f0da7", size = 13991951 }, + { url = "https://files.pythonhosted.org/packages/22/97/dfb1a31bb46686f09e68ea6ac5c63fdee0d22d7b23b8f3f7ea07712869ef/numpy-1.24.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7215847ce88a85ce39baf9e89070cb860c98fdddacbaa6c0da3ffb31b3350bd5", size = 17278923 }, + { url = "https://files.pythonhosted.org/packages/35/e2/76a11e54139654a324d107da1d98f99e7aa2a7ef97cfd7c631fba7dbde71/numpy-1.24.4-cp311-cp311-win32.whl", hash = "sha256:4979217d7de511a8d57f4b4b5b2b965f707768440c17cb70fbf254c4b225238d", size = 12422446 }, + { url = "https://files.pythonhosted.org/packages/d8/ec/ebef2f7d7c28503f958f0f8b992e7ce606fb74f9e891199329d5f5f87404/numpy-1.24.4-cp311-cp311-win_amd64.whl", hash = "sha256:b7b1fc9864d7d39e28f41d089bfd6353cb5f27ecd9905348c24187a768c79694", size = 14834466 }, + { url = "https://files.pythonhosted.org/packages/11/10/943cfb579f1a02909ff96464c69893b1d25be3731b5d3652c2e0cf1281ea/numpy-1.24.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1452241c290f3e2a312c137a9999cdbf63f78864d63c79039bda65ee86943f61", size = 19780722 }, + { url = "https://files.pythonhosted.org/packages/a7/ae/f53b7b265fdc701e663fbb322a8e9d4b14d9cb7b2385f45ddfabfc4327e4/numpy-1.24.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:04640dab83f7c6c85abf9cd729c5b65f1ebd0ccf9de90b270cd61935eef0197f", size = 13843102 }, + { url = "https://files.pythonhosted.org/packages/25/6f/2586a50ad72e8dbb1d8381f837008a0321a3516dfd7cb57fc8cf7e4bb06b/numpy-1.24.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5425b114831d1e77e4b5d812b69d11d962e104095a5b9c3b641a218abcc050e", size = 14039616 }, + { url = "https://files.pythonhosted.org/packages/98/5d/5738903efe0ecb73e51eb44feafba32bdba2081263d40c5043568ff60faf/numpy-1.24.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd80e219fd4c71fc3699fc1dadac5dcf4fd882bfc6f7ec53d30fa197b8ee22dc", size = 17316263 }, + { url = "https://files.pythonhosted.org/packages/d1/57/8d328f0b91c733aa9aa7ee540dbc49b58796c862b4fbcb1146c701e888da/numpy-1.24.4-cp38-cp38-win32.whl", hash = "sha256:4602244f345453db537be5314d3983dbf5834a9701b7723ec28923e2889e0bb2", size = 12455660 }, + { url = "https://files.pythonhosted.org/packages/69/65/0d47953afa0ad569d12de5f65d964321c208492064c38fe3b0b9744f8d44/numpy-1.24.4-cp38-cp38-win_amd64.whl", hash = "sha256:692f2e0f55794943c5bfff12b3f56f99af76f902fc47487bdfe97856de51a706", size = 14868112 }, + { url = "https://files.pythonhosted.org/packages/9a/cd/d5b0402b801c8a8b56b04c1e85c6165efab298d2f0ab741c2406516ede3a/numpy-1.24.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2541312fbf09977f3b3ad449c4e5f4bb55d0dbf79226d7724211acc905049400", size = 19816549 }, + { url = "https://files.pythonhosted.org/packages/14/27/638aaa446f39113a3ed38b37a66243e21b38110d021bfcb940c383e120f2/numpy-1.24.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9667575fb6d13c95f1b36aca12c5ee3356bf001b714fc354eb5465ce1609e62f", size = 13879950 }, + { url = "https://files.pythonhosted.org/packages/8f/27/91894916e50627476cff1a4e4363ab6179d01077d71b9afed41d9e1f18bf/numpy-1.24.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3a86ed21e4f87050382c7bc96571755193c4c1392490744ac73d660e8f564a9", size = 14030228 }, + { url = "https://files.pythonhosted.org/packages/7a/7c/d7b2a0417af6428440c0ad7cb9799073e507b1a465f827d058b826236964/numpy-1.24.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d11efb4dbecbdf22508d55e48d9c8384db795e1b7b51ea735289ff96613ff74d", size = 17311170 }, + { url = "https://files.pythonhosted.org/packages/18/9d/e02ace5d7dfccee796c37b995c63322674daf88ae2f4a4724c5dd0afcc91/numpy-1.24.4-cp39-cp39-win32.whl", hash = "sha256:6620c0acd41dbcb368610bb2f4d83145674040025e5536954782467100aa8835", size = 12454918 }, + { url = "https://files.pythonhosted.org/packages/63/38/6cc19d6b8bfa1d1a459daf2b3fe325453153ca7019976274b6f33d8b5663/numpy-1.24.4-cp39-cp39-win_amd64.whl", hash = "sha256:befe2bf740fd8373cf56149a5c23a0f601e82869598d41f8e188a0e9869926f8", size = 14867441 }, + { url = "https://files.pythonhosted.org/packages/a4/fd/8dff40e25e937c94257455c237b9b6bf5a30d42dd1cc11555533be099492/numpy-1.24.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:31f13e25b4e304632a4619d0e0777662c2ffea99fcae2029556b17d8ff958aef", size = 19156590 }, + { url = "https://files.pythonhosted.org/packages/42/e7/4bf953c6e05df90c6d351af69966384fed8e988d0e8c54dad7103b59f3ba/numpy-1.24.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95f7ac6540e95bc440ad77f56e520da5bf877f87dca58bd095288dce8940532a", size = 16705744 }, + { url = "https://files.pythonhosted.org/packages/fc/dd/9106005eb477d022b60b3817ed5937a43dad8fd1f20b0610ea8a32fcb407/numpy-1.24.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:e98f220aa76ca2a977fe435f5b04d7b3470c0a2e6312907b37ba6068f26787f2", size = 14734290 }, +] + +[[package]] +name = "psutil" +version = "6.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/18/c7/8c6872f7372eb6a6b2e4708b88419fb46b857f7a2e1892966b851cc79fc9/psutil-6.0.0.tar.gz", hash = "sha256:8faae4f310b6d969fa26ca0545338b21f73c6b15db7c4a8d934a5482faa818f2", size = 508067 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c5/66/78c9c3020f573c58101dc43a44f6855d01bbbd747e24da2f0c4491200ea3/psutil-6.0.0-cp27-none-win32.whl", hash = "sha256:02b69001f44cc73c1c5279d02b30a817e339ceb258ad75997325e0e6169d8b35", size = 249766 }, + { url = "https://files.pythonhosted.org/packages/e1/3f/2403aa9558bea4d3854b0e5e567bc3dd8e9fbc1fc4453c0aa9aafeb75467/psutil-6.0.0-cp27-none-win_amd64.whl", hash = "sha256:21f1fb635deccd510f69f485b87433460a603919b45e2a324ad65b0cc74f8fb1", size = 253024 }, + { url = "https://files.pythonhosted.org/packages/0b/37/f8da2fbd29690b3557cca414c1949f92162981920699cd62095a984983bf/psutil-6.0.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c588a7e9b1173b6e866756dde596fd4cad94f9399daf99ad8c3258b3cb2b47a0", size = 250961 }, + { url = "https://files.pythonhosted.org/packages/35/56/72f86175e81c656a01c4401cd3b1c923f891b31fbcebe98985894176d7c9/psutil-6.0.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ed2440ada7ef7d0d608f20ad89a04ec47d2d3ab7190896cd62ca5fc4fe08bf0", size = 287478 }, + { url = "https://files.pythonhosted.org/packages/19/74/f59e7e0d392bc1070e9a70e2f9190d652487ac115bb16e2eff6b22ad1d24/psutil-6.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fd9a97c8e94059b0ef54a7d4baf13b405011176c3b6ff257c247cae0d560ecd", size = 290455 }, + { url = "https://files.pythonhosted.org/packages/cd/5f/60038e277ff0a9cc8f0c9ea3d0c5eb6ee1d2470ea3f9389d776432888e47/psutil-6.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2e8d0054fc88153ca0544f5c4d554d42e33df2e009c4ff42284ac9ebdef4132", size = 292046 }, + { url = "https://files.pythonhosted.org/packages/8b/20/2ff69ad9c35c3df1858ac4e094f20bd2374d33c8643cf41da8fd7cdcb78b/psutil-6.0.0-cp37-abi3-win32.whl", hash = "sha256:a495580d6bae27291324fe60cea0b5a7c23fa36a7cd35035a16d93bdcf076b9d", size = 253560 }, + { url = "https://files.pythonhosted.org/packages/73/44/561092313ae925f3acfaace6f9ddc4f6a9c748704317bad9c8c8f8a36a79/psutil-6.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:33ea5e1c975250a720b3a6609c490db40dae5d83a4eb315170c4fe0d8b1f34b3", size = 257399 }, + { url = "https://files.pythonhosted.org/packages/7c/06/63872a64c312a24fb9b4af123ee7007a306617da63ff13bcc1432386ead7/psutil-6.0.0-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:ffe7fc9b6b36beadc8c322f84e1caff51e8703b88eee1da46d1e3a6ae11b4fd0", size = 251988 }, +] + +[[package]] +name = "pygments" +version = "2.18.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8e/62/8336eff65bcbc8e4cb5d05b55faf041285951b6e80f33e2bff2024788f31/pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199", size = 4891905 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f7/3f/01c8b82017c199075f8f788d0d906b9ffbbc5a47dc9918a945e13d5a2bda/pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a", size = 1205513 }, +] + +[[package]] +name = "pypubsub" +version = "4.0.3" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1a/41/a0aceb552d8ec63bb1e8223d130f9dd0f736470036d75d708183b104a2cb/Pypubsub-4.0.3-py3-none-any.whl", hash = "sha256:7f716bae9388afe01ff82b264ba8a96a8ae78b42bb1f114f2716ca8f9e404e2a", size = 61368 }, +] + +[[package]] +name = "pywin32" +version = "306" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/08/dc/28c668097edfaf4eac4617ef7adf081b9cf50d254672fcf399a70f5efc41/pywin32-306-cp310-cp310-win32.whl", hash = "sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d", size = 8506422 }, + { url = "https://files.pythonhosted.org/packages/d3/d6/891894edec688e72c2e308b3243fad98b4066e1839fd2fe78f04129a9d31/pywin32-306-cp310-cp310-win_amd64.whl", hash = "sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8", size = 9226392 }, + { url = "https://files.pythonhosted.org/packages/8b/1e/fc18ad83ca553e01b97aa8393ff10e33c1fb57801db05488b83282ee9913/pywin32-306-cp311-cp311-win32.whl", hash = "sha256:e65028133d15b64d2ed8f06dd9fbc268352478d4f9289e69c190ecd6818b6407", size = 8507689 }, + { url = "https://files.pythonhosted.org/packages/7e/9e/ad6b1ae2a5ad1066dc509350e0fbf74d8d50251a51e420a2a8feaa0cecbd/pywin32-306-cp311-cp311-win_amd64.whl", hash = "sha256:a7639f51c184c0272e93f244eb24dafca9b1855707d94c192d4a0b4c01e1100e", size = 9227547 }, + { url = "https://files.pythonhosted.org/packages/91/20/f744bff1da8f43388498503634378dbbefbe493e65675f2cc52f7185c2c2/pywin32-306-cp311-cp311-win_arm64.whl", hash = "sha256:70dba0c913d19f942a2db25217d9a1b726c278f483a919f1abfed79c9cf64d3a", size = 10388324 }, + { url = "https://files.pythonhosted.org/packages/14/91/17e016d5923e178346aabda3dfec6629d1a26efe587d19667542105cf0a6/pywin32-306-cp312-cp312-win32.whl", hash = "sha256:383229d515657f4e3ed1343da8be101000562bf514591ff383ae940cad65458b", size = 8507705 }, + { url = "https://files.pythonhosted.org/packages/83/1c/25b79fc3ec99b19b0a0730cc47356f7e2959863bf9f3cd314332bddb4f68/pywin32-306-cp312-cp312-win_amd64.whl", hash = "sha256:37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e", size = 9227429 }, + { url = "https://files.pythonhosted.org/packages/1c/43/e3444dc9a12f8365d9603c2145d16bf0a2f8180f343cf87be47f5579e547/pywin32-306-cp312-cp312-win_arm64.whl", hash = "sha256:5821ec52f6d321aa59e2db7e0a35b997de60c201943557d108af9d4ae1ec7040", size = 10388145 }, + { url = "https://files.pythonhosted.org/packages/0e/57/c3ec32b498f24a2392404d1f0fd29f47a3f7339d7d579df7a0560cff337c/pywin32-306-cp38-cp38-win32.whl", hash = "sha256:e4c092e2589b5cf0d365849e73e02c391c1349958c5ac3e9d5ccb9a28e017b3a", size = 8632118 }, + { url = "https://files.pythonhosted.org/packages/fa/80/a6b22e031590cc5f4fcbd5bf4bcf63a9dabce9d59065f53add99a8caaec5/pywin32-306-cp38-cp38-win_amd64.whl", hash = "sha256:e8ac1ae3601bee6ca9f7cb4b5363bf1c0badb935ef243c4733ff9a393b1690c0", size = 9373699 }, + { url = "https://files.pythonhosted.org/packages/7e/7f/419c4fcadcaa374a0ae41cbdf6c3a81452892dd6c523aea629d17e49146e/pywin32-306-cp39-cp39-win32.whl", hash = "sha256:e25fd5b485b55ac9c057f67d94bc203f3f6595078d1fb3b458c9c28b7153a802", size = 8573451 }, + { url = "https://files.pythonhosted.org/packages/1c/f7/24d8ed4fd9c43b90354df7764f81f0dd5e623f9a50f1538f90fe085d6dff/pywin32-306-cp39-cp39-win_amd64.whl", hash = "sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4", size = 9312883 }, +] + +[[package]] +name = "robotframework-ride" +version = "2.1.dev78" +source = { editable = "." } +dependencies = [ + { name = "psutil" }, + { name = "pygments" }, + { name = "pypubsub" }, + { name = "pywin32", marker = "platform_system == 'Windows'" }, + { name = "wxpython" }, +] + +[package.metadata] +requires-dist = [ + { name = "psutil" }, + { name = "pygments" }, + { name = "pypubsub" }, + { name = "pywin32", marker = "platform_system == 'Windows'" }, + { name = "wxpython" }, +] + +[[package]] +name = "six" +version = "1.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/71/39/171f1c67cd00715f190ba0b100d606d440a28c93c7714febeca8b79af85e/six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", size = 34041 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254", size = 11053 }, +] + +[[package]] +name = "wxpython" +version = "4.2.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy", marker = "python_full_version < '3.12'" }, + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a4/f5/8c272764770f47fd419cc2eff4c4fa1c0681c71bcc2f3158b3a83d1339ff/wxPython-4.2.2.tar.gz", hash = "sha256:5dbcb0650f67fdc2c5965795a255ffaa3d7b09fb149aa8da2d0d9aa44e38e2ba", size = 57358880 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c3/22/946b24359cda568101f2dec80dce7e05ddb254a26ae2f472f7c0ed26c622/wxPython-4.2.2-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:a83bc118417b715ee8fd7143faaf51adaa041ccae22cc6de99bc7f7bb7fc44ef", size = 30271553 }, + { url = "https://files.pythonhosted.org/packages/37/9d/77809b6bddd07ee7452865001052717128c7185e1aca74d84661d13d9d5e/wxPython-4.2.2-cp310-cp310-win32.whl", hash = "sha256:68923029a7e236374002af25c14aa311922b80f8d63e1f088e6176e12640fa3e", size = 14661277 }, + { url = "https://files.pythonhosted.org/packages/c9/e2/31503268ae20e854ec583d29d26c9857fb07964c96acb52ee1d82f034c03/wxPython-4.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:a1f506144173010ae3354980d1a1da6ffcaeed87f2b1be9eef43f60fc8faeaa4", size = 16663694 }, + { url = "https://files.pythonhosted.org/packages/48/20/390530466538829eb8aa75256514d6fd976da2f272a068f4d00f90ab8013/wxPython-4.2.2-cp311-cp311-macosx_10_10_universal2.whl", hash = "sha256:0fe3cb940f5da4f0ec61c3cf37e63c0f577f09a7b9a5d3d7cfc59399eb18cb3b", size = 30391688 }, + { url = "https://files.pythonhosted.org/packages/2d/49/ff72728cc7964b01982b6f6677e21f517beb4cc3424a350b651f55ad1ec7/wxPython-4.2.2-cp311-cp311-win32.whl", hash = "sha256:f63863d52272f8c841b22e7128a339b6d93f3e4d8307d98ea346fa1ec6fbc13b", size = 14366610 }, + { url = "https://files.pythonhosted.org/packages/0c/97/d829af5e0ea3472b1988dfd3e286c269c8207841b31bb73feb01494676a6/wxPython-4.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:008c55c60abb3dd66229e1849f10f6a7d5b9af9cc62de40fb9dec144686b5c4d", size = 16408142 }, + { url = "https://files.pythonhosted.org/packages/5b/21/d59602847c7e2a577145cb85d0d02a7bb04abd7bcbbc4f316ac54d27a583/wxPython-4.2.2-cp312-cp312-macosx_10_10_universal2.whl", hash = "sha256:5d536110a674cb44ff6112d910b26fe6b062d670a6c3840a41036abfe83acc6b", size = 30430388 }, + { url = "https://files.pythonhosted.org/packages/e5/ed/0b1e149646bcc857646c830a40de13cff0aa76852f2946d62d78b692bb6f/wxPython-4.2.2-cp312-cp312-win32.whl", hash = "sha256:5298662b83792fa8e66e60fdc298dbc317fcf61c68facc506182c2914faef0db", size = 14372221 }, + { url = "https://files.pythonhosted.org/packages/8c/5c/5eced6cd588083d797e538d444a24a2ead8253205c3cb6bcc0cd11080281/wxPython-4.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:ea0cc206d40d6749f98f60eae2105382685e26bbf6c5a62a853543a0f3fd0ad7", size = 16416508 }, + { url = "https://files.pythonhosted.org/packages/4a/6c/d53b5ae0c039190f07f2cb77715f7b0c3c68588ff922e8f894c0c6b8f9e9/wxPython-4.2.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e3a6f0eebb8176135991851adbb1648da7f3beb0378752117c3b7ee05e8e55c6", size = 30431860 }, + { url = "https://files.pythonhosted.org/packages/fa/b1/bc06c1abb212e1a2358588037d4fa5d5f4c962dd287478f4d54e425854a0/wxPython-4.2.2-cp313-cp313-win32.whl", hash = "sha256:c9310864b088d0f68d212360f261c8fec46a543c952da21805177519622b8524", size = 14368445 }, + { url = "https://files.pythonhosted.org/packages/8c/df/5a9eca8dab4367c3efc27a42a6d6d407347261c2b7be5cead468d22f99e0/wxPython-4.2.2-cp313-cp313-win_amd64.whl", hash = "sha256:d8548ce4165e214601083d0d5767dba854a5e14f4e0ed4dbe56e2daf193a4575", size = 16416599 }, + { url = "https://files.pythonhosted.org/packages/a8/5a/3a2c64e16f5cde14971a51a2bb0d84b6ddc8b804328297ea19b16a6c8742/wxPython-4.2.2-cp38-cp38-macosx_12_0_x86_64.whl", hash = "sha256:e5ba9b29f64b466d2926c4a5c5a1b624f635c20b1c23ba27064ac9216d858b90", size = 30270768 }, + { url = "https://files.pythonhosted.org/packages/da/f4/2c56d18dd24b64f7f2cfe2fee7a6019df50275fe3e73b4ed4aed2263a03e/wxPython-4.2.2-cp38-cp38-win32.whl", hash = "sha256:a391eacd10d0ba16333a186819307641803b0dc7a066d5fe4bd1c13f1cd2f44e", size = 14669817 }, + { url = "https://files.pythonhosted.org/packages/78/ff/ab0dce2bb452b3d492605f19bd8512d476da6f7c1f8456170a3da20a2466/wxPython-4.2.2-cp38-cp38-win_amd64.whl", hash = "sha256:b68a4cc0e5b648a0856ffd399ce04e6b750d9dbfba325c4a1f6201dc8e9e4886", size = 16671692 }, + { url = "https://files.pythonhosted.org/packages/4d/2b/a517bb16a88345a02c65f730b98df329359d2311f8e17858d591d94d890b/wxPython-4.2.2-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:a8c58154e05bb63e7b45dfd0ee379d354dc3372199a858260575e2817908434f", size = 30271692 }, + { url = "https://files.pythonhosted.org/packages/19/24/1ea07b24e0b474cfe7c902fecf227349b20033eefd41e41aa49aeca3750b/wxPython-4.2.2-cp39-cp39-win32.whl", hash = "sha256:f7b879f29d91ef847c5e88bfb7c34a732a35f016896b1b7f87bc3e3d2d0a5a96", size = 14661285 }, + { url = "https://files.pythonhosted.org/packages/c1/eb/3941ec23abe967347b56dccbbcea664252de6b8ce85e62b0f5b5f8c132f9/wxPython-4.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:c8d6509f5579732329df70070966a5d8152890e0213f9305801048f5e7408158", size = 16664306 }, +]