Files
pgadmin4/pgadmin4-desktop
Antonio Larrosa dc38b702ad Accepting request 1145351 from home:alarrosa:branches:server:database:postgresql
- Fix shebang of pgadmin4-desktop to use python3.11

- New pgadmin4-cloud subpackage that includes now the cloud
  dependencies and make the pgadmin4-cloud package optional so
  it's now optional to depend on the azure/aws/google python
  packages.
- Add patch to let pgadmin4 work without cloud support:
  * make-cloud-packages-optional.patch

- Add a optipng script that actually uses pngcrush to compress png
  images so we don't depend on optipng which is not available in
  SLE.
- Fix pgadmin4-desktop to use a timer instead of threads. It seems
  there's an issue the way python threads were used with Qt5 that
  made the script fail to update the systray menu when pgadmin was
  started.
- Add missing python-typer dependency
- Add pgadmin4-user.conf file to create the pgadmin user/group
  using systemd with the new system-user-pgadmin package.

- Replace yarn (which is not available in SLE) with
  local-npm-registry.
- Add node_modules service and node_modules.obscpio /
  node_modules.spec.inc source files which replace vendor.tar.xz
  that is now removed.
- package_deps.patch - dependency fixes
- package_git_local.patch - dependency fixes that are needed *after*
  generating package-lock.json since only registry-supplied packages
  are available locally. 
- Update update-vendor.sh script.

OBS-URL: https://build.opensuse.org/request/show/1145351
OBS-URL: https://build.opensuse.org/package/show/server:database:postgresql/pgadmin4?expand=0&rev=65
2024-02-09 06:41:39 +00:00

136 lines
4.6 KiB
Python

#!/usr/bin/python3
#
# This is a small script that tries to replace pgadmin4-runtime as
# a desktop version of pgadmin4.
# pgadmin4-runtime uses NW.js (which is based on Chromium and Node.js) which
# makes it hard to package in a standard way.
# pgadmin4-desktop tries to be a simple replacement which just runs pgadmin4
# in runtime mode but uses Qt6 for the GUI in order to show an icon in the
# system tray and provide two options: open a new browser window with pgAdmin
# and quit the application.
#
# This script is released under the PostgreSQL License.
# (C) 2023 Antonio Larrosa <alarrosa@suse.com>
import subprocess
import os
import os.path
import uuid
import socket
import time
import sys
import fcntl
from PyQt5.QtWidgets import QApplication, QSystemTrayIcon, QMenu, QSplashScreen, QAction
from PyQt5.QtGui import QIcon, QPixmap, QImage, QPalette, QPainter
from PyQt5.QtCore import QTimer, Qt
class PGAdminDesktop(QApplication):
def __init__(self):
super().__init__(sys.argv)
self.environ = os.environ
self.pgadmin_process = None
self.url = None
self.setQuitOnLastWindowClosed(False)
self.aboutToQuit.connect(self.cleanup)
self.create_ui()
pixmap = self.load_splash_pixmap()
if pixmap:
self.splash = QSplashScreen(pixmap)
self.splash.showMessage("Starting pgAdmin.", Qt.AlignmentFlag.AlignBottom)
self.splash.show()
else:
self.splash = None
self.run_pgadmin_server()
QTimer.singleShot(500, self.open_pgadmin)
def load_splash_pixmap(self):
paths = [path + '/pgadmin4/assets/welcome_logo.svg' for path in sys.path]
paths = [path for path in paths if os.path.exists(path)]
if not paths:
return None
return QPixmap(paths[0])
def run_pgadmin_server(self):
if 'PGADMIN_INT_KEY' not in self.environ:
self.environ['PGADMIN_INT_KEY'] = str(uuid.uuid4())
if 'PGADMIN_INT_PORT' not in self.environ:
self.environ['PGADMIN_INT_PORT'] = '5051'
self.environ['PGADMIN_SERVER_MODE'] = 'OFF'
self.pgadmin_process = subprocess.Popen(['pgadmin4'],
env=self.environ, shell=True)
def create_ui(self):
icon = QIcon.fromTheme("pgadmin4")
self.tray = QSystemTrayIcon()
self.tray.setIcon(icon)
self.tray.setVisible(True)
menu = QMenu()
self.title = QAction("pgAdmin")
self.title.setEnabled(False)
menu.addAction(self.title)
menu.addSeparator()
self.openPGAdminAction = QAction("New Window")
menu.addAction(self.openPGAdminAction)
self.openPGAdminAction.triggered.connect(self.open_pgadmin)
self.quitAction = QAction("Quit")
menu.addAction(self.quitAction)
self.quitAction.triggered.connect(self.quit)
self.tray.setContextMenu(menu)
def check_if_pgadmin_is_running(self):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(1)
result = sock.connect_ex(('127.0.0.1',
int(self.environ['PGADMIN_INT_PORT'])))
if result == 0:
if self.splash:
self.splash.hide()
port = self.environ['PGADMIN_INT_PORT']
key = self.environ['PGADMIN_INT_KEY']
subprocess.run(["xdg-open", f"http://127.0.0.1:{port}/?key={key}"])
self.openPGAdminAction.setText("New Window")
self.openPGAdminAction.setEnabled(True)
else:
self.checks_for_pgadmin += 1
if self.checks_for_pgadmin < 15:
dots = "." * (self.checks_for_pgadmin % 3 + 1)
self.openPGAdminAction.setText("Opening pgAdmin" + dots)
if self.splash and not self.splash.isHidden():
self.splash.showMessage("Starting pgAdmin" + dots, Qt.AlignmentFlag.AlignBottom)
QTimer.singleShot(1000, self.check_if_pgadmin_is_running)
else:
error_msg = 'Timeout waiting for pgAdmin to start. Exiting...'
print(error_msg)
self.splash.showMessage(error_msg, Qt.AlignmentFlag.AlignBottom)
QTimer.singleShot(10000, self.quit)
def open_pgadmin(self):
self.openPGAdminAction.setText("Opening pgAdmin...")
self.openPGAdminAction.setEnabled(False)
self.checks_for_pgadmin = 0
QTimer.singleShot(1000, self.check_if_pgadmin_is_running)
def cleanup(self):
self.pgadmin_process.kill()
if __name__ == '__main__':
app = PGAdminDesktop()
sys.exit(app.exec())