From 4308a0a1657be020a6fe5e082e69a47e18c5fc46 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Wed, 21 Feb 2024 10:39:17 +0100 Subject: [PATCH] Added meson build system Thanks to https://codeberg.org/valos/Komikku for showing how to do it --- .gitignore | 1 + README.md | 1 + bin/melon.in | 96 +++++++++++++++++++++++++++++ bin/meson.build | 30 +++++++++ data/icu.ccw.Melon.desktop.in | 15 +++++ melon.svg => data/icu.ccw.Melon.svg | 0 data/meson.build | 33 ++++++++++ main.py | 35 +++-------- melon/application.py | 25 ++++++++ meson.build | 48 +++++++++++++++ 10 files changed, 258 insertions(+), 26 deletions(-) create mode 100755 bin/melon.in create mode 100644 bin/meson.build create mode 100644 data/icu.ccw.Melon.desktop.in rename melon.svg => data/icu.ccw.Melon.svg (100%) create mode 100644 data/meson.build create mode 100644 melon/application.py create mode 100644 meson.build diff --git a/.gitignore b/.gitignore index eeb8a6e..5237bc1 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ **/__pycache__ +build/ diff --git a/README.md b/README.md index 0e62321..1af7382 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ Of course, you are welcome to send issues and pull requests via email as well: ## 🧩 Requirements - `python3` - `py3-beautifulsoup4` +- `py3-lxml` - `py3-requests` - `py3-sqlite3` - `gtk4.0` diff --git a/bin/melon.in b/bin/melon.in new file mode 100755 index 0000000..41c5198 --- /dev/null +++ b/bin/melon.in @@ -0,0 +1,96 @@ +#!@PYTHON@ + +# @prettyname@ -- @description@ +# +# Copyright (C) 2019-2024 @authorfullname@ <@authoremail@> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import gettext +import locale +import os +import sys + +sys.path.insert(1, '@pythondir@') + +builddir = os.environ.get('MESON_BUILD_ROOT') +if builddir: + sys.dont_write_bytecode = True + sys.path.insert(1, os.environ['MESON_SOURCE_ROOT']) + xdg_data_dir = os.path.join(builddir, '@prefix@', '@datadir@') + os.putenv('XDG_DATA_DIRS', '%s:%s' % (xdg_data_dir, os.getenv('XDG_DATA_DIRS', '/usr/local/share/:/usr/share/'))) + + +def install_excepthook(): + """ Make sure we exit when an unhandled exception occurs. """ + old_hook = sys.excepthook + + def new_hook(etype, evalue, etb): + print('Error: An unhandled exception occurs') + + old_hook(etype, evalue, etb) + + context = GLib.main_context_default() + done = False + while context.iteration(): + if done: + continue + app = Gio.Application.get_default() + if app.window: + app.window.quit(force=True) + else: + app.quit() + done = True + + sys.exit() + + sys.excepthook = new_hook + + +if __name__ == '__main__': + import gi + + gi.require_version('Gtk', '4.0') + gi.require_version('Adw', '1') + + from gi.repository import Gio + from gi.repository import GLib + from gi.repository import Gtk + + install_excepthook() + + # Why both locale and gettext are needed? + # gettext works for the python part but not for XML UI files! + try: + locale.textdomain('@projectname@') + locale.bindtextdomain('@projectname@', '@localedir@') + except AttributeError as e: + # Python built without gettext support doesn't have bindtextdomain() and textdomain() + print('Could not bind the gettext translation domain. Some translations will not work.') + print('Error: {}'.format(e)) + gettext.textdomain('@projectname@') + gettext.bindtextdomain('@projectname@', '@localedir@') + + from @projectname@.application import Application + + Application.application_id = '@appid@' + Application.version = '@VERSION@' + app = Application() + + try: + status = app.run(sys.argv) + except SystemExit as e: + status = e.code + + sys.exit(status) diff --git a/bin/meson.build b/bin/meson.build new file mode 100644 index 0000000..1b93f2a --- /dev/null +++ b/bin/meson.build @@ -0,0 +1,30 @@ +# Profiles +conf = configuration_data() + +conf.set('VERSION', meson.project_version()) +conf.set('PYTHON', py_installation.full_path()) +conf.set('prefix', prefix) +conf.set('datadir', datadir) +conf.set('pkgdatadir', pkgdatadir) +conf.set('pythondir', join_paths(prefix, pythondir)) +conf.set('localedir', join_paths(prefix, localedir)) +conf.set('projectname', meson.project_name()) +conf.set('prettyname', prettyname) +conf.set('description', description) +conf.set('authorfullname', authorfullname) +conf.set('authoremail', authoremail) +conf.set('appid', app_id) + +# Install launch script and add `run` target +configure_file( + input: meson.project_name() + '.in', + output: meson.project_name(), + configuration: conf, + install: true, + install_dir: get_option('bindir') +) + +script_path = join_paths(meson.project_build_root(), 'bin', meson.project_name()) +run_target('run', + command: [script_path] +) diff --git a/data/icu.ccw.Melon.desktop.in b/data/icu.ccw.Melon.desktop.in new file mode 100644 index 0000000..4e69211 --- /dev/null +++ b/data/icu.ccw.Melon.desktop.in @@ -0,0 +1,15 @@ +[Desktop Entry] +Name=@prettyname@ +Comment=@description@ +Exec=@bindir@/@projectname@ %U +# Translators: Do NOT translate or transliterate this text (this is an icon file name)! +Icon=@appid@ +Terminal=false +Type=Application +StartupNotify=true +Categories=Graphics;Network;Viewer;GTK;GNOME; +# Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +Keywords=viewer;videos;stream;browse; +X-GNOME-UsesNotifications=true +# Translators: Do NOT translate or transliterate this text (these are enum types)! +X-Purism-FormFactor=Workstation;Mobile; diff --git a/melon.svg b/data/icu.ccw.Melon.svg similarity index 100% rename from melon.svg rename to data/icu.ccw.Melon.svg diff --git a/data/meson.build b/data/meson.build new file mode 100644 index 0000000..71615ba --- /dev/null +++ b/data/meson.build @@ -0,0 +1,33 @@ +scalable_dir = join_paths(datadir, 'icons/hicolor/scalable/apps') +install_data ( + '@0@.svg'.format(app_id), + install_dir: scalable_dir, +) + +gnome = import('gnome') + +# +# .desktop file +# +desktop_conf = configuration_data() +desktop_conf.set('bindir', join_paths(prefix, bindir)) +desktop_conf.set('prettyname', prettyname) +# .desktop comment now hardcoded for better i18n support +desktop_conf.set('description', description) +desktop_conf.set('appid', app_id) +desktop_conf.set('projectname', meson.project_name()) + +desktop_file = configure_file( + input: base_id + '.desktop.in', + output: app_id + '.desktop', + configuration: desktop_conf, + install: true, + install_dir: join_paths(datadir, 'applications') +) + +# +# Dependencies +# +dependency('glib-2.0') +dependency('gtk4', version: '>=4.12.1') +dependency('libadwaita-1', version: '>=1.4.0') diff --git a/main.py b/main.py index 2cbae11..659fc77 100644 --- a/main.py +++ b/main.py @@ -1,29 +1,12 @@ +# manual quick-run script import sys -import gi -gi.require_version('Gtk', '4.0') -gi.require_version('Adw', '1') -from gi.repository import Gtk, Adw, Gio, GLib +from melon.application import Application +Application.application_id = "icu.ccw.melon" +app = Application() -from melon.window import MainWindow -from melon.models import init_db -from melon.servers.utils import get_server_instance, load_server, get_servers_list +try: + status = app.run(sys.argv) +except SystemExit as e: + status = e.code -class MyApp(Adw.Application): - def __init__(self, **kwargs): - super().__init__(**kwargs) - # set name - GLib.set_application_name("Melon") - # initialize db - init_db() - # this has to wait till the db is initialized - for _,server_data in get_servers_list().items(): - instance = get_server_instance(server_data) - load_server(instance) - self.connect('activate', self.on_activate) - - def on_activate(self, app): - self.win = MainWindow(application=app) - self.win.present() - -app = MyApp(application_id="icu.ccw.melon") -app.run(sys.argv) +sys.exit(status) diff --git a/melon/application.py b/melon/application.py new file mode 100644 index 0000000..5aace2f --- /dev/null +++ b/melon/application.py @@ -0,0 +1,25 @@ +import gi +gi.require_version('Gtk', '4.0') +gi.require_version('Adw', '1') +from gi.repository import Gtk, Adw, Gio, GLib + +from melon.window import MainWindow +from melon.models import init_db +from melon.servers.utils import get_server_instance, load_server, get_servers_list + +class Application(Adw.Application): + def __init__(self, **kwargs): + super().__init__(**kwargs) + # set name + GLib.set_application_name("Melon") + # initialize db + init_db() + # this has to wait till the db is initialized + for _,server_data in get_servers_list().items(): + instance = get_server_instance(server_data) + load_server(instance) + self.connect('activate', self.on_activate) + + def on_activate(self, app): + self.win = MainWindow(application=app) + self.win.present() diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..b0a782a --- /dev/null +++ b/meson.build @@ -0,0 +1,48 @@ +project( + 'melon', + version: '0.1.0', + meson_version: '>= 0.59.0', + license: 'GPL-3.0-or-later' +) + +description = 'Video player that aims to be mobile friendly. Stream videos on the go from multiple sources.' +prettyname = 'Melon' + +authornickname = 'comcloudway' +authorfullname = 'Jakob Meier' +authoremail = 'comcloudway@ccw.icu' + +domainname = 'ccw' +domainext = 'icu' + +gitrepo = 'https://codeberg.org/' + authornickname + '/' + prettyname + +python = import('python') +py_installation = python.find_installation('python3') +if not py_installation.found() + error('No valid python3 binary found') +else + message('Found python3 binary') +endif + +prefix = get_option('prefix') # should be /usr +bindir = get_option('bindir') # should be /bin +datadir = get_option('datadir') # should be /usr/share +pkgdatadir = join_paths(prefix, datadir, meson.project_name()) +pythondir = py_installation.get_install_dir() +localedir = join_paths(prefix, get_option('localedir')) + +base_id = '.'.join([domainext, domainname, prettyname]) +app_id_aspath = '/'.join([domainext, domainname, prettyname]) +app_id = base_id + +install_subdir(meson.project_name(), install_dir: pythondir) +subdir('data') +subdir('bin') + +# Run required post-install steps +gnome.post_install( + gtk_update_icon_cache: true, + glib_compile_schemas: true, + update_desktop_database: true, +) -- 2.38.5