Commit a5146264 authored by Bilal Elmoussaoui's avatar Bilal Elmoussaoui

remove pgp option and various improvements

parent 51cf54c0
......@@ -17,4 +17,4 @@
along with Authenticator. If not, see <http://www.gnu.org/licenses/>.
"""
from .application import Application
from .utils import can_use_qrscanner, load_pixbuf, load_pixbuf_from_provider
from .utils import load_pixbuf, load_pixbuf_from_provider
......@@ -22,14 +22,13 @@ from gi import require_version
require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib, Gio, Gdk, GObject
from .widgets import Window, AboutDialog, import_json, export_json, import_pgp_json, export_pgp_json
from .widgets import Window, AboutDialog, import_json, export_json
from .models import Settings, Clipboard, Logger
class Application(Gtk.Application):
"""Authenticator application object."""
instance = None
USE_QRSCANNER = True
IS_DEVEL = False
is_locked = GObject.Property(type=bool, default=False)
......@@ -59,7 +58,6 @@ class Application(Gtk.Application):
def do_startup(self):
"""Startup the application."""
Gtk.Application.do_startup(self)
# Unlock the keyring
self.__generate_menu()
self.__setup_actions()
self.set_property("is-locked", Settings.get_default().can_be_locked)
......@@ -99,9 +97,7 @@ class Application(Gtk.Application):
export_menu = Gio.Menu.new()
import_menu.append_item(Gio.MenuItem.new(_("from a plain-text JSON file"), "app.import_json"))
import_menu.append_item(Gio.MenuItem.new(_("from an OpenPGP-encrypted JSON file"), "app.import_pgp_json"))
export_menu.append_item(Gio.MenuItem.new(_("in a plain-text JSON file"), "app.export_json"))
export_menu.append_item(Gio.MenuItem.new(_("in an OpenPGP-encrypted JSON file"), "app.export_pgp_json"))
backup_content.insert_submenu(0, _("Restore"), import_menu)
backup_content.insert_submenu(1, _("Backup"), export_menu)
......@@ -113,20 +109,20 @@ class Application(Gtk.Application):
main_content = Gio.Menu.new()
# Night mode action
main_content.append_item(Gio.MenuItem.new(_("Preferences"), "app.settings"))
main_content.append_item(Gio.MenuItem.new(_("About Authenticator"), "app.about"))
main_content.append_item(Gio.MenuItem.new(_("Donate"), "app.donate"))
main_content.append_item(Gio.MenuItem.new(_("Keyboard Shortcuts"), "app.shortcuts"))
main_content.append_item(Gio.MenuItem.new(_("About Authenticator"), "app.about"))
help_section = Gio.MenuItem.new_section(None, main_content)
self._menu.append_item(help_section)
def __setup_actions(self):
self.__add_action("about", self.__on_about)
self.__add_action("shortcuts", self.__on_shortcuts)
self.__add_action("donate", self.__on_donate)
self.__add_action("quit", self.__on_quit)
self.__add_action("settings", self.__on_settings, "is_locked")
self.__add_action("import_json", self.__on_import_json, "is_locked")
self.__add_action("import_pgp_json", self.__on_import_pgp_json, "is_locked")
self.__add_action("export_json", self.__on_export_json, "is_locked")
self.__add_action("export_pgp_json", self.__on_export_pgp_json, "is_locked")
if Settings.get_default().can_be_locked:
self.__add_action("lock", self.__on_lock, "is_locked")
......@@ -161,6 +157,10 @@ class Application(Gtk.Application):
def __on_lock(self, *_):
self.set_property("is-locked", True)
def __on_donate(self, *_):
paypal_url = "https://www.paypal.me/BilalELMoussaoui"
Gio.app_info_launch_default_for_uri(paypal_url)
@staticmethod
def __on_about(*_):
"""
......@@ -193,29 +193,6 @@ class Application(Gtk.Application):
if filename:
BackupJSON.export_file(filename)
@staticmethod
def __on_import_pgp_json(*_):
from .widgets import GPGRestoreWindow
filename = import_pgp_json(Window.get_default())
if filename:
gpg_window = GPGRestoreWindow(filename)
gpg_window.set_transient_for(Window.get_default())
gpg_window.show_all()
@staticmethod
def __on_export_pgp_json(*_):
from .models import BackupPGPJSON
filename = export_pgp_json(Window.get_default())
if filename:
def export_pgp(_, fingerprint):
BackupPGPJSON.export_file(filename, fingerprint)
from .widgets.backup import FingprintPGPWindow
fingerprint_window = FingprintPGPWindow(filename)
fingerprint_window.set_transient_for(Window.get_default())
fingerprint_window.connect("selected", export_pgp)
fingerprint_window.show_all()
@staticmethod
def __on_settings(*_):
from .widgets import SettingsWindow
......
......@@ -18,7 +18,7 @@
"""
from .account import Account
from .accounts_manager import AccountsManager
from .backup import BackupJSON, BackupPGPJSON
from .backup import BackupJSON
from .clipboard import Clipboard
from .database import Database
from .keyring import Keyring
......@@ -27,5 +27,3 @@ from .otp import OTP
from .qr_reader import QRReader
from .screenshot import GNOMEScreenshot
from .settings import Settings
from .gnupg import GPG
......@@ -76,24 +76,3 @@ class BackupJSON:
gfile = Gio.File.new_for_uri(uri)
accounts = gfile.load_contents()[1].decode("utf-8")
Backup.import_accounts(json.loads(accounts))
class BackupPGPJSON:
def __init__(self):
pass
@staticmethod
def export_file(uri, fingerprint):
from .gnupg import GPG
accounts = Backup.export_accounts()
data = json.dumps(accounts, sort_keys=True, indent=4)
encrypted_data = GPG.get_default().encrypt(data, fingerprint)
gfile = Gio.File.new_for_uri(uri)
stream = gfile.replace(None,
False,
Gio.FileCreateFlags.REPLACE_DESTINATION,
None)
data_stream = Gio.DataOutputStream.new(stream)
data_stream.put_string(str(encrypted_data), None)
stream.close()
"""
Copyright © 2017 Bilal Elmoussaoui <bil.elmoussaoui@gmail.com>
This file is part of Authenticator.
Authenticator 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.
Authenticator 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 ould have received a copy of the GNU General Public License
along with Authenticator. If not, see <http://www.gnu.org/licenses/>.
"""
import gnupg
from .settings import Settings
class GPG(gnupg.GPG):
instance = None
def __init__(self):
gnupg.GPG.__init__(self, gnupghome=Settings.get_default().gpg_location)
@staticmethod
def get_default():
if GPG.instance is None:
GPG.instance = GPG()
return GPG.instance
def get_keys(self):
return {
"public": self.list_keys(),
"private": self.list_keys(True)
}
def decrypt_json(self, filename, paraphrase, out_file):
with open(filename, 'rb') as infile:
status = self.decrypt_file(infile, passphrase=paraphrase, output=out_file)
return status
def ecrypt_json(self, json_obj, fingerprint):
return self.encrypt(json_obj, recipients=fingerprint)
......@@ -45,8 +45,6 @@ class QRReader:
Logger.error("Invalid QR image")
return None
except ImportError:
from ..application import Application
Application.USE_QRSCANNER = False
QRReader.ZBAR_FOUND = False
def is_valid(self):
......
......@@ -28,7 +28,7 @@ class Settings(Gio.Settings):
# Default Settings instance
instance = None
# Settings schema
SCHEMA = "com.github.bilelmoussaoui.Authenticator"
SCHEMA = "@APP_ID@"
def __init__(self):
Gio.Settings.__init__(self)
......@@ -93,14 +93,6 @@ class Settings(Gio.Settings):
"""
self.set_boolean("is-maximized", is_maximized)
@property
def gpg_location(self):
return self.get_string('gpg-location')
@gpg_location.setter
def gpg_location(self, new_location):
self.set_string("gpg-location", new_location)
@property
def is_locked(self):
return self.get_boolean("is-locked")
......
......@@ -24,11 +24,6 @@ require_version('Gtk', '3.0')
from gi.repository import Gtk, GdkPixbuf, GLib, Gio
def can_use_qrscanner():
desktop = environ.get("XDG_CURRENT_DESKTOP", "").lower()
return desktop == "gnome"
def load_pixbuf(icon_name, size):
pixbuf = None
theme = Gtk.IconTheme.get_default()
......
......@@ -24,5 +24,4 @@ from .login import LoginWidget
from .search_bar import SearchBar
from .window import Window
from .settings import SettingsWindow
from .utils import import_json, export_json, import_pgp_json, export_pgp_json
from .backup import GPGRestoreWindow
from .utils import import_json, export_json
......@@ -28,7 +28,7 @@ from gi.repository import Gd, Gio, Gtk, GObject, Gdk
from ..headerbar import HeaderBarButton
from ...models import OTP
from ...utils import can_use_qrscanner, load_pixbuf_from_provider
from ...utils import load_pixbuf_from_provider
class AddAccountWindow(Gtk.Window):
......@@ -58,12 +58,10 @@ class AddAccountWindow(Gtk.Window):
header_bar.pack_end(self.add_btn)
# QR code scan btn
from ...application import Application
self.scan_btn = HeaderBarButton("qrscanner-symbolic",
_("Scan QR code"))
if Application.USE_QRSCANNER and can_use_qrscanner():
self.scan_btn.connect("clicked", self._on_scan)
header_bar.pack_end(self.scan_btn)
self.scan_btn.connect("clicked", self._on_scan)
header_bar.pack_end(self.scan_btn)
# Back btn
self.close_btn = Gtk.Button()
......
"""
Copyright © 2017 Bilal Elmoussaoui <bil.elmoussaoui@gmail.com>
This file is part of Authenticator.
Authenticator 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.
Authenticator 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 Authenticator. If not, see <http://www.gnu.org/licenses/>.
"""
from .gnupg import GPGRestoreWindow, FingprintPGPWindow
"""
Copyright © 2017 Bilal Elmoussaoui <bil.elmoussaoui@gmail.com>
This file is part of Authenticator.
Authenticator 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.
Authenticator 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 Authenticator. If not, see <http://www.gnu.org/licenses/>.
"""
from gettext import gettext as _
from gi import require_version
require_version("Gd", "1.0")
require_version("Gtk", "3.0")
from gi.repository import Gd, Gtk, GObject, GLib
from os import path
from tempfile import NamedTemporaryFile
from ...models import GPG, Logger
from ..settings import SettingsBoxWithEntry, ClickableSettingsBox
class GPGRestoreWindow(Gtk.Window):
def __init__(self, filename):
Gtk.Window.__init__(self)
self.set_position(Gtk.WindowPosition.CENTER_ON_PARENT)
self.set_size_request(400, 200)
self.set_title(_("GPG paraphrase"))
self.resize(400, 200)
self._filename = filename
self._build_widgets()
def _build_widgets(self):
header_bar = Gtk.HeaderBar()
header_bar.set_show_close_button(True)
header_bar.set_title(_("GPG paraphrase"))
apply_btn = Gtk.Button()
apply_btn.set_label(_("Import"))
apply_btn.get_style_context().add_class("suggested-action")
apply_btn.connect("clicked", self.__on_apply)
header_bar.pack_end(apply_btn)
self.set_titlebar(header_bar)
container = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
self.paraphrase_widget = SettingsBoxWithEntry(_("Paraphrase"), True)
container.pack_start(self.paraphrase_widget, False, False, 0)
container.get_style_context().add_class("settings-main-container")
self.add(container)
def __on_apply(self, *__):
from ...models import BackupJSON
try:
paraphrase = self.paraphrase_widget.entry.get_text()
if not paraphrase:
paraphrase = " "
output_file = path.join(GLib.get_user_cache_dir(),
path.basename(NamedTemporaryFile().name))
status = GPG.get_default().decrypt_json(self._filename, paraphrase, output_file)
if status.ok:
BackupJSON.import_file(output_file)
self.destroy()
else:
self.__send_notification(_("There was an error during the import of the encrypted file."))
except AttributeError:
Logger.error("[GPG] Invalid JSON file.")
def __send_notification(self, message):
notification = Gd.Notification()
notification.set_timeout(5)
container = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
notification_lbl = Gtk.Label()
notification_lbl.set_text(message)
container.pack_start(notification_lbl, False, False, 3)
notification.add(container)
notification_parent = self.get_children()[-1]
notification_parent.add(notification)
notification_parent.reorder_child(notification, 0)
self.show_all()
class FingprintPGPWindow(Gtk.Window, GObject.GObject):
"""Main Window object."""
__gsignals__ = {
'selected': (GObject.SignalFlags.RUN_LAST, None, (str,))
}
def __init__(self, filename):
Gtk.Window.__init__(self)
self.set_position(Gtk.WindowPosition.CENTER_ON_PARENT)
self.set_size_request(600, 600)
self.set_title(_("GPG fingerprint"))
self.resize(600, 600)
self._filename = filename
self._build_widgets()
def _build_widgets(self):
header_bar = Gtk.HeaderBar()
header_bar.set_show_close_button(True)
header_bar.set_title(_("GPG fingerprint"))
self.set_titlebar(header_bar)
container = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
keys = GPG.get_default().get_keys()
self.__add_keys(keys["public"], _("Public keys"), container)
self.__add_keys(keys["private"], _("Private keys"), container)
container.get_style_context().add_class("settings-main-container")
self.add(container)
def __add_keys(self, keys, label, container):
key_label = Gtk.Label()
key_label.set_halign(Gtk.Align.START)
key_label.get_style_context().add_class("gpg-key-lbl")
key_label.set_text(label)
container.pack_start(key_label, False, False, 0)
for key in keys:
uid = key.get("uids", [""])[0]
fingerprint = key.get("fingerprint", "")
key_widget = ClickableSettingsBox(uid, fingerprint)
key_widget.connect("button-press-event", self.__finger_print_selected, fingerprint)
container.pack_start(key_widget, False, False, 0)
def __finger_print_selected(self, _, __, fingerprint):
self.emit("selected", fingerprint)
self.destroy()
......@@ -249,14 +249,6 @@ class SettingsWindow(Gtk.Window):
behaviour_container.pack_start(app_password, False, False, 0)
self.stack.add_titled(behaviour_container, "behaviour", _("Behaviour"))
backup_container = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
gpg_location = ClickableSettingsBox(_("GPG keys location"),
Settings.get_default().gpg_location)
gpg_location.connect("button-press-event", self.__on_gpg_location_clicked)
backup_container.pack_start(gpg_location, False, False, 0)
self.stack.add_titled(backup_container, "backup", _("Backup"))
self.add(self.stack)
def __on_app_can_be_locked_changed(self, __, state):
......@@ -286,13 +278,6 @@ class SettingsWindow(Gtk.Window):
gtk_settings.set_property("gtk-application-prefer-dark-theme",
state)
def __on_gpg_location_clicked(self, gpg_location_widget, _):
from .utils import open_directory
directory = open_directory(self)
if directory:
Settings.get_default().gpg_location = directory
gpg_location_widget.secondary_lbl.set_text(directory)
def __on_clear_database_clicked(self, *__):
notification = Gd.Notification()
notification.set_timeout(5)
......
......@@ -38,16 +38,6 @@ def export_json(parent):
return __open_file_chooser(parent, mimetype, Gtk.FileChooserAction.SAVE)
def import_pgp_json(parent):
mimetype = {'type': "application/pgp-encrypted", 'name': _("Encrypted GPG files")}
return __open_file_chooser(parent, mimetype)
def export_pgp_json(parent):
mimetype = {'type': "application/pgp-encrypted", 'name': _("Encrypted GPG files")}
return __open_file_chooser(parent, mimetype, Gtk.FileChooserAction.SAVE)
def open_directory(parent):
file_chooser = Gtk.FileChooserDialog()
file_chooser.set_action(Gtk.FileChooserAction.SELECT_FOLDER)
......
......@@ -40,8 +40,6 @@ flatpak install flathub com.github.bilelmoussaoui.Authenticator
- `ninja`
- `pyotp`
- `libsecret`
- `python-gnupg`
- `gnupg`
Those dependencies are only used if you build the application with QR code scanner support
- `Pillow`
......
......@@ -24,7 +24,7 @@ import gettext
import locale
import sys
from os import path
from gettext import gettext as _
from gi import require_version
require_version('GIRepository', '2.0')
......@@ -33,18 +33,22 @@ from gi.repository import Gio, GIRepository
sys.path.insert(1, '@PYTHON_EXEC_DIR@')
sys.path.insert(1, '@PYTHON_DIR@')
_ = gettext.gettext
if __name__ == "__main__":
def prepare_locale():
locale.bindtextdomain('Authenticator', '@LOCALE_DIR@')
locale.textdomain('Authenticator')
gettext.bindtextdomain('Authenticator', '@LOCALE_DIR@')
gettext.textdomain('Authenticator')
VERSION = "@VERSION@"
GIRepository.Repository.prepend_search_path(
path.join('@LIB_DIR@', 'girepository-1.0'))
def prepare_gir():
gir_repository_path = path.join('@LIB_DIR@', 'girepository-1.0')
GIRepository.Repository.prepend_search_path(gir_repository_path)
GIRepository.Repository.prepend_library_path('@LIB_DIR@')
if __name__ == "__main__":
prepare_locale()
prepare_gir()
parser = argparse.ArgumentParser(prog="Authenticator")
parser.add_argument("--debug", "-d", action="store_true",
help=_("Start in debug mode"))
......@@ -52,12 +56,11 @@ if __name__ == "__main__":
help=_("Authenticator version number"))
args = parser.parse_args()
resource = Gio.resource_load(path.join('@DATA_DIR@',
'com.github.bilelmoussaoui.Authenticator.gresource'))
resource = Gio.resource_load(path.join('@DATA_DIR@', '@APP_ID@.gresource'))
Gio.Resource._register(resource)
from Authenticator.models import Logger
from Authenticator.models import Logger
level = Logger.ERROR
if args.debug:
level = Logger.DEBUG
......@@ -66,15 +69,12 @@ if __name__ == "__main__":
Logger.set_level(level)
if args.version:
sys.exit("Version : " + str(VERSION))
sys.exit("Version : @VERSION@")
else:
try:
from Authenticator import Application
app = Application.get_default()
Application.IS_DEVEL = "@PROFILE@" == 'Devel'
Application.USE_QRSCANNER = "@ENABLE_QRSCANNER@" == 'True'
exit_status = app.run(None)
sys.exit(exit_status)
except KeyboardInterrupt:
......
......@@ -22,13 +22,6 @@
"--filesystem=xdg-run/dconf", "--filesystem=~/.config/dconf:ro",
"--talk-name=ca.desrt.dconf", "--env=DCONF_USER_CONFIG_DIR=.config/dconf"
],
"build-options": {
"cflags": "-O2 -g",
"cxxflags": "-O2 -g",
"env": {
"V": "1"
}
},
"modules": [{
"name": "zbar",
"config-opts": [
......@@ -129,18 +122,6 @@
"sha256": "4dbbece533650f2aeb6c8d1f41cf424614d2877d7331c48a9eed35ae9f949626"
}]
},
{
"name": "python-gnupg",
"buildsystem": "simple",
"build-commands": [
"pip3 install --prefix=/app python_gnupg-0.4.3-py2.py3-none-any.whl"
],
"sources": [{
"type": "file",
"url": "https://files.pythonhosted.org/packages/4a/87/76ead690afc4c7710012ede242537cd9807dde9de6299e65d075925c0b02/python_gnupg-0.4.3-py2.py3-none-any.whl",
"sha256": "faa69bab58ed0936f0ccf96c99b92369b7a1819305d37dfe5c927d21a437a09d"
}]
},
{
"name": "libhandy",
"buildsystem": "meson",
......
......@@ -7,6 +7,6 @@ Exec=authenticator
Terminal=false
Categories=GNOME;GTK;Security;Network;
Keywords=Gnome;GTK;Verification;
Icon=@icon@
Icon=@appid@
StartupNotify=true
StartupWMClass=com.github.bilelmoussaoui.Authenticator
<?xml version="1.0" encoding="UTF-8"?>
<schemalist>
<schema path="/com/github/bilelmoussaoui/Authenticator/" id="com.github.bilelmoussaoui.Authenticator" gettext-domain="Authenticator">
<schema path="@schema-path@" id="@app-id@" gettext-domain="Authenticator">
<key name="window-position" type="ai">
<default>[0,0]</default>
<summary>Default window position</summary>
......@@ -16,11 +16,6 @@
<summary>Default window maximized behaviour</summary>
<description></description>
</key>
<key name="gpg-location" type="s">
<default>'~/.gnupg/'</default>
<summary>GPG keys location</summary>
<description></description>
</key>
<key name="is-locked" type="b">
<default>false</default>
<summary>Whether the application is locked with a password or not</summary>
......
......@@ -15,6 +15,7 @@ foreach theme : icon_themes
symbolic_icon = join_paths(symbolic_dir, meson.project_name() + '-symbolic.svg')
dest_symbolic = join_paths(get_option('prefix'), 'share/icons', symbolic_dir)
install_data(symbolic_icon,
install_dir: dest_symbolic, rename: '@0@'.format(application_id) + '-symbolic.svg')
install_dir: dest_symbolic,
rename: '@0@'.format(application_id) + '-symbolic.svg')
endforeach
gnome.compile_resources(
meson.project_name(),
application_id,
meson.project_name() + '.gresource.xml',
gresource_bundle: true,
source_dir: '.',
install_dir: join_paths(datadir, meson.project_name()),
install_dir: join_paths(get_option('datadir'), meson.project_name()),
install: true
)
install_data(
meson.project_name() + '.gschema.xml',
install_dir : join_paths(datadir, 'glib-2.0/schemas')
# Install gschema
gschema_conf = configuration_data()
gschema_conf.set('app-id', application_id)
if get_option('profile') == 'development'
gschema_conf.set('schema-path', '/com/github/bilelmoussaoui/Authenticator/')
else
gschema_conf.set('schema-path', '/com/github/bilelmoussaoui/AuthenticatorDevel/')
endif
configure_file(
configuration: gschema_conf,
input: files(meson.project_name() + '.gschema.xml.in'),
install_dir: join_paths(get_option('datadir'), 'glib-2.0', 'schemas'),
output: '@0@.gschema.xml'.format(application_id)
)
# GNOME Shell Search Provider Service
search_service_provider_conf = configuration_data()
search_service_provider_conf.set('appid', application_id)
search_service_provider_conf.set('profile', profile)
configure_file(
configuration: search_service_provider_conf,
input: files(meson.project_name() + '.SearchProvider.service.in'),
install_dir: join_paths(datadir, 'gnome-shell', 'search-providers'),
install_dir: join_paths(get_option('datadir'), 'gnome-shell', 'search-providers'),
output: '@0@.SearchProvider.service'.format(application_id)
)
# GNOME Shell Search Provider
search_provider_conf = configuration_data()
search_provider_conf.set('appid', application_id)
search_provider_conf.set('profile', profile)
configure_file(
configuration: search_provider_conf,
input: files(meson.project_name() + '.SearchProvider.ini.in'),
install_dir: join_paths(datadir, 'gnome-shell', 'search-providers'),
install_dir: join_paths(get_option('datadir'), 'gnome-shell', 'search-providers'),
output: '@0@.SearchProvider.ini'.format(application_id)
)
# FreeDesktop Desktop File
desktop_conf = configuration_data()
desktop_conf.set('icon', application_id)
desktop = i18n.merge_file(
desktop_conf.set('appid', application_id)
desktop_file = i18n.merge_file(
'desktop',
input: configure_file(
input: files(meson.project_name() + '.desktop.in.in'),
......@@ -46,12 +57,22 @@ desktop = i18n.merge_file(
po_dir: join_paths(meson.source_root(), 'po'),
type: 'desktop',
install: true,
install_dir: join_paths(datadir, 'applications')
install_dir: join_paths(get_option('datadir'), 'applications')
)
# Validate Desktop File
desktop_file_validate = find_program('desktop-file-validate', required: false)
if desktop_file_validate.found()
test (
'Validate desktop file',
desktop_file_validate,
args: desktop_file.full_path()
)
endif
# Freedesktop AppData File
appdata_conf = configuration_data()
appdata_conf.set('appid', application_id)
appdata = i18n.merge_file(
appdata_file = i18n.merge_file(
'appdata',
input: configure_file(
input: files(meson.project_name() + '.appdata.xml.in.in'),
......@@ -61,30 +82,15 @@ appdata = i18n.merge_file(
output: '@0@.appdata.xml'.format(application_id),
po_dir: join_paths(meson.source_root(), 'po'),
install: true,
install_dir: join_paths(datadir, 'appdata')
install_dir: join_paths(get_option('datadir'), 'metainfo')
)
desktop_file_validate = find_program('desktop-file-validate', required:false)
if desktop_file_validate.found()
test (
'Validate desktop file',
desktop_file_validate,
args: join_paths(meson.current_build_dir(), '@0@.desktop'.format(application_id))
)
endif
# Validate AppData File
appstreamcli = find_program('appstream-util', required:false)
if appstreamcli.found()
test (
'Validate appdata file',