1
0
mirror of https://github.com/bpozdena/OneDriveGUI.git synced 2026-10-24 04:59:17 +03:00

Merge pull request #301 from maikwoehl/feature/packagable

Create resources to make it packable as python package
This commit is contained in:
Boris Pozdena
2026-09-15 14:24:26 +02:00
73 changed files with 124 additions and 69 deletions

View File

@@ -4,7 +4,7 @@ script:
- mkdir -p AppDir/usr
- mkdir -p AppDir/usr/share/icons/hicolor/48x48
- cp src AppDir/usr -r
- cp src/resources/images/OneDriveGUI.png AppDir/usr/share/icons/hicolor/48x48
- cp src/onedrive_gui/resources/images/OneDriveGUI.png AppDir/usr/share/icons/hicolor/48x48
- python3 -m pip install --ignore-installed --prefix=/usr --no-cache-dir --root=AppDir -r ./requirements.txt
- rm -rf AppDir/usr/local/lib/python3.10/dist-packages/PySide6/Qt/qml/
- rm -rf AppDir/usr/local/lib/python3.10/dist-packages/PySide6/examples/
@@ -13,7 +13,9 @@ script:
- rm -f AppDir/usr/local/lib/python3.10/dist-packages/PySide6/{assistant,designer,linguist,lrelease,lupdate}
- rm -f AppDir/usr/local/lib/python3.10/dist-packages/PySide6/{Qt3D*,QtBluetooth*,QtCharts*,QtConcurrent*,QtDataVisualization*,QtDBus*,QtDesigner*,QtHelp*,QtMultimedia*,QtNetwork*,QtOpenGL*,QtPositioning*,QtPrintSupport*,QtQml*,QtQuick*,QtRemoteObjects*,QtScxml*,QtSensors*,QtSerialPort*,QtSql*,QtStateMachine*,QtSvg*,QtTest*,QtWeb*,QtXml*}
- shopt -s extglob
- rm -rf AppDir/usr/local/lib/python3.10/dist-packages/PySide6/Qt/lib/!(libQt6OpenGL*|libQt6XcbQpa*|libQt6Wayland*|libQt6Egl*|libicudata*|libicuuc*|libicui18n*|libQt6DBus*|libQt6Network*|libQt6Qml*|libQt6Core*|libQt6Gui*|libQt6Widgets*|libQt6Svg*|libQt6UiTools*)
- rm -rf AppDir/usr/local/lib/python3.12/dist-packages/PySide6/Qt/lib/!(libQt6OpenGL*|libQt6XcbQpa*|libQt6Wayland*|libQt6Egl*|libicudata*|libicuuc*|libicui18n*|libQt6DBus*|libQt6Network*|libQt6Qml*|libQt6Core*|libQt6Gui*|libQt6Widgets*|libQt6Svg*|libQt6UiTools*)
- python3 -m build
- find dist -type f -name *.whl -exec python3 -m pip install --ignore-installed --prefix=/usr --no-cache-dir --root=AppDir {} \;
AppDir:
@@ -25,7 +27,7 @@ AppDir:
icon: OneDriveGUI
version: 1.3.2
exec: usr/bin/python3.10
exec_args: "$APPDIR/usr/src/OneDriveGUI.py $@"
exec_args: "-m onedrive_gui $@"
apt:
arch: amd64

1
MANIFEST.in Normal file
View File

@@ -0,0 +1 @@
global-include *.png *.ui default_config *.autosave

View File

@@ -50,6 +50,21 @@ A GUI for [Linux OneDrive Client](https://github.com/abraunegg/onedrive) with mu
## AUR
- An AUR package [onedrivegui-git](https://aur.archlinux.org/packages/onedrivegui-git) is available (maintainer: Integral).
## Python Package
Use setuptools and build to build the package:
```
python3 -m pip install setuptools build
python3 -m build
```
That produces a wheel package in the directory `dist/` than can be installed:
```
python3 -m pip install dist/onedrive_gui-1.3.2-py3-none-any.whl
```
## Running from Source
1) Ensure Python3 and [pip](https://pip.pypa.io/en/stable/installation/) are installed on your system.
@@ -66,13 +81,13 @@ A GUI for [Linux OneDrive Client](https://github.com/abraunegg/onedrive) with mu
1) Start OneDrive GUI:
```sh
cd src/
python3 OneDriveGUI.py
python3 -m onedrive_gui
```
Optionally, you can detach the GUI from the terminal by using the command below:
```sh
cd src/
nohup python3 OneDriveGUI.py > /dev/null 2>&1 &
nohup python3 -m onedrive_gui > /dev/null 2>&1 &
```
# Usage

View File

@@ -2,7 +2,7 @@
# Step 1: Function to extract version from OneDriveGUI.py without importing
get_version() {
FILE_PATH="src/options.py"
FILE_PATH="src/onedrive_gui/options.py"
VERSION=$(grep -Po '^version\s*=\s*"\K[^\"]+' "$FILE_PATH")
if [ -z "$VERSION" ]; then
@@ -28,7 +28,22 @@ update_yaml() {
fi
}
# Step 3: Build the AppImage using appimage-builder
# Step 3: Update the indented version line in pyproject.toml
update_pyproject() {
PYPROJECT_TOML_FILE="pyproject.toml"
if [ -f "$PYPROJECT_TOML_FILE" ]; then
echo "Updating version in $PYPROJECT_TOML_FILE..."
# Use sed to match the indented version line and update it
sed -i "s/^\(version =\).*/\1 \"$VERSION\"/" "$PYPROJECT_TOML_FILE"
echo "Version updated to $VERSION in the indented version line of $PYPROJECT_TOML_FILE"
else
echo "$PYPROJECT_TOML_FILE not found."
exit 1
fi
}
# Step 4: Build the AppImage using appimage-builder
build_appimage() {
if ! command -v appimage-builder &> /dev/null; then
echo "appimage-builder could not be found. Please install it first."
@@ -49,4 +64,5 @@ build_appimage() {
# Main script execution
get_version
update_yaml
update_pyproject
build_appimage

View File

@@ -34,7 +34,15 @@ docker run \
set -e
echo "Installing dependencies..."
apt update
apt install -y wget python3 python3-pip fuse gtk-update-icon-cache
apt install -y \
fuse \
gtk-update-icon-cache \
python3 \
python3-pip \
python3-venv \
wget
pip install build setuptools
echo "Installing appimage-builder..."
wget -q -O /tmp/appimage-builder.AppImage https://github.com/AppImageCrafters/appimage-builder/releases/download/v1.1.0/appimage-builder-1.1.0-x86_64.AppImage

14
pyproject.toml Normal file
View File

@@ -0,0 +1,14 @@
[project]
name = "onedrive-gui"
version = "1.3.2"
description = "A simple GUI for Linux OneDrive Client, with multi-account support."
readme = "README.md"
requires-python = ">=3.8"
license-files = ["LICENSE"]
[project.scripts]
onedrive-gui = "onedrive_gui.OneDriveGUI:main"
[build-system]
requires = ["setuptools >= 61.0"]
build-backend = "setuptools.build_meta"

View File

@@ -10,10 +10,10 @@ from PySide6.QtGui import QIcon
from PySide6.QtWidgets import QApplication
from logger import logger
from .logger import logger
from global_config import DIR_PATH
from .global_config import DIR_PATH
app = QApplication(sys.argv)
@@ -22,15 +22,20 @@ app.setDesktopFileName("OneDriveGUI")
app.setWindowIcon(QIcon(DIR_PATH + "/resources/images/icons8-cloud-80.png"))
from options import gui_settings, global_config, version
from global_config import save_global_config
from main_window import MainWindow
from .options import gui_settings, global_config, version
from .global_config import save_global_config
from .main_window import MainWindow
workers = {}
def main_window_start_state():
# Determine if OneDriveGUI should start maximized, minimized to tray or minimized to taskbar/dock.
# This should help ensure the GUI does not just disappear on Gnome without system tray extension.
def main():
logging.info(f"Starting OneDriveGUI v{version}")
if len(global_config) > 0:
save_global_config(global_config)
main_window = MainWindow()
if gui_settings.get("start_minimized") == "True" or len(global_config) == 0:
try:
if main_window.tray.isSystemTrayAvailable():
@@ -45,16 +50,5 @@ def main_window_start_state():
logging.info("[GUI] Starting OneDriveGUI maximized")
workers = {}
if __name__ == "__main__":
logging.info(f"Starting OneDriveGUI v{version}")
if len(global_config) > 0:
save_global_config(global_config)
main_window = MainWindow()
main_window_start_state()
app.exec()

View File

@@ -0,0 +1,3 @@
from .OneDriveGUI import main
main()

View File

@@ -3,19 +3,19 @@ from PySide6.QtWidgets import QWidget, QFileDialog
# Imports for GUI settings window
from ui.ui_gui_settings_window import Ui_gui_settings_window
from .ui.ui_gui_settings_window import Ui_gui_settings_window
import re
import os
from settings.gui_settings import gui_settings
from .settings.gui_settings import gui_settings
import logging
# from logger import logger
from global_config import DIR_PATH, PROFILES_FILE
from .global_config import DIR_PATH, PROFILES_FILE
class GuiSettingsWindow(QWidget, Ui_gui_settings_window):
@@ -119,7 +119,7 @@ class GuiSettingsWindow(QWidget, Ui_gui_settings_window):
def sync_autostart_on_startup(self):
"""Sync autostart file with saved setting on app startup."""
from utils.autostart import enable_autostart, disable_autostart, is_autostart_enabled
from .utils.autostart import enable_autostart, disable_autostart, is_autostart_enabled
# Get the saved setting
autostart_should_be_enabled = self.get_check_box_state("autostart_enabled")
@@ -150,7 +150,7 @@ class GuiSettingsWindow(QWidget, Ui_gui_settings_window):
def save_settings(self):
"""Save all settings and sync autostart file with checkbox state."""
from utils.autostart import enable_autostart, disable_autostart
from .utils.autostart import enable_autostart, disable_autostart
from PySide6.QtWidgets import QMessageBox
# Save all settings first

View File

@@ -3,7 +3,7 @@ import sys
import re
import logging
import logging.handlers as handlers
from settings.gui_settings import gui_settings
from .settings.gui_settings import gui_settings
def config_debug_level():

View File

@@ -15,12 +15,12 @@ from PySide6.QtWidgets import (
# Imports for main window.
from ui.ui_mainwindow import Ui_MainWindow
from ui.ui_process_status_page import Ui_status_page
from .ui.ui_mainwindow import Ui_MainWindow
from .ui.ui_process_status_page import Ui_status_page
# Import for login windows.
from ui.ui_external_login import Ui_ExternalLoginWindow
from .ui.ui_external_login import Ui_ExternalLoginWindow
import re
@@ -31,27 +31,27 @@ import requests
import subprocess
from wizard import setup_wizard
from profile_settings_window import profile_settings_window
from .wizard import setup_wizard
from .profile_settings_window import profile_settings_window
from options import (
from .options import (
global_config,
client_bin_path,
gui_settings,
version,
)
from utils.utils import humanize_file_size, shorten_path, format_relative_time
from workers import WorkerThread, MaintenanceWorker, TaskList, workers
from gui_settings_window import gui_settings_window
from .utils.utils import humanize_file_size, shorten_path, format_relative_time
from .workers import WorkerThread, MaintenanceWorker, TaskList, workers
from .gui_settings_window import gui_settings_window
import logging
# from logger import logger
from global_config import DIR_PATH, PROFILES_FILE, save_global_config
from .global_config import DIR_PATH, PROFILES_FILE, save_global_config
try:
from ui.ui_login import Ui_LoginWindow
from .ui.ui_login import Ui_LoginWindow
except ImportError:
logging.warning("Failed to import ui_login. This is expected if you are running AppImage version.")
@@ -66,12 +66,12 @@ class MainWindow(QMainWindow, Ui_MainWindow):
def __init__(self):
# Expose this instance as main_window.main_window_instance so other modules
# (e.g. profile_settings_window) can reach it without a circular import.
import main_window
from . import main_window
main_window.main_window_instance = self
# Access setup_wizard from wizard module to avoid circular imports
import wizard
from . import wizard
wizard.setup_wizard.show_main_window_signal.connect(self.show)
wizard.setup_wizard.add_profile_signal.connect(self.add_profile)

View File

@@ -1,8 +1,8 @@
import copy
from utils.utils import get_installed_client_version, config_client_bin_path
from global_config import create_global_config
from .utils.utils import get_installed_client_version, config_client_bin_path
from .global_config import create_global_config
from settings.gui_settings import gui_settings
from .settings.gui_settings import gui_settings
client_bin_path = gui_settings.get("frameless_window")

View File

@@ -12,8 +12,8 @@ from PySide6.QtWidgets import (
)
# Imports for Profiles windows.
from ui.ui_profile_settings_window import Ui_profile_settings_window
from ui.ui_profile_settings_page import Ui_profile_settings
from .ui.ui_profile_settings_window import Ui_profile_settings_window
from .ui.ui_profile_settings_page import Ui_profile_settings
import re
import os
@@ -22,20 +22,20 @@ import subprocess
from configparser import ConfigParser
# Import setup_wizard after importing wizard, keeping it at the bottom to avoid circular imports
import wizard
from global_config import save_global_config
from . import wizard
from .global_config import save_global_config
# Import main_window (lazy import to avoid circular references)
import main_window
from options import client_bin_path, global_config
from options import temp_global_config
from . import main_window
from .options import client_bin_path, global_config
from .options import temp_global_config
from workers import workers
from .workers import workers
import logging
# from logger import logger
from global_config import DIR_PATH, PROFILES_FILE
from .global_config import DIR_PATH, PROFILES_FILE
class ProfileSettingsWindow(QWidget, Ui_profile_settings_window):

View File

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 420 B

After

Width:  |  Height:  |  Size: 420 B

View File

Before

Width:  |  Height:  |  Size: 511 B

After

Width:  |  Height:  |  Size: 511 B

View File

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 100 KiB

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 118 B

After

Width:  |  Height:  |  Size: 118 B

View File

Before

Width:  |  Height:  |  Size: 169 B

After

Width:  |  Height:  |  Size: 169 B

View File

Before

Width:  |  Height:  |  Size: 291 B

After

Width:  |  Height:  |  Size: 291 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 161 B

After

Width:  |  Height:  |  Size: 161 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 629 B

After

Width:  |  Height:  |  Size: 629 B

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1 @@
# do not delete

View File

@@ -0,0 +1 @@
# do not delete

View File

@@ -6,7 +6,7 @@ from datetime import datetime
import logging
# from logger import logger
from settings.gui_settings import gui_settings
from ..settings.gui_settings import gui_settings
def humanize_file_size(num, suffix="B"):

View File

@@ -22,8 +22,8 @@ import requests
import subprocess
from configparser import ConfigParser
from global_config import save_global_config, read_config
from options import (
from .global_config import save_global_config, read_config
from .options import (
global_config,
temp_global_config,
client_bin_path,
@@ -31,9 +31,9 @@ from options import (
version,
)
from workers import MaintenanceWorker
from .workers import MaintenanceWorker
import logging
from global_config import DIR_PATH, PROFILES_FILE
from .global_config import DIR_PATH, PROFILES_FILE
class SetupWizard(QWizard):

View File

@@ -5,7 +5,7 @@ from PySide6.QtGui import QFontMetrics, QIcon
# Imports for main window.
from ui.ui_list_item_widget import Ui_list_item_widget
from .ui.ui_list_item_widget import Ui_list_item_widget
import re
@@ -13,8 +13,8 @@ import time
import subprocess
from datetime import datetime
from global_config import save_global_config
from options import (
from .global_config import save_global_config
from .options import (
# main_window,
global_config,
temp_global_config,
@@ -24,13 +24,13 @@ from options import (
version,
)
from utils.utils import humanize_file_size, shorten_path
from .utils.utils import humanize_file_size, shorten_path
import logging
# from logger import logger
from global_config import DIR_PATH, PROFILES_FILE
from .global_config import DIR_PATH, PROFILES_FILE
class WorkerThread(QThread):

View File