GitLab repository storage has been migrated to hashed layout. Please contact Infrastructure team if you notice any issues with repositories or hooks.

...
 
Commits (30)
image: snapcore/snapcraft:stable
stages:
- build
cache:
paths:
- _ccache/
variables:
MESON_TEST_TIMEOUT_MULTIPLIER: 2
G_MESSAGES_DEBUG: all
MESON_COMMON_OPTIONS: "--buildtype debug --prefix /usr"
fedora-x86_64:
image: registry.gitlab.gnome.org/gnome/gnome-software/fedora:v1
stage: build
except:
- tags
script:
- git clone https://gitlab.freedesktop.org/pwithnall/malcontent.git ./malcontent
- pushd ./malcontent
- git checkout tags/0.4.0
- meson setup ${MESON_COMMON_OPTIONS} _build
- ninja -C _build
- sudo ninja -C _build install
- popd
- meson ${MESON_COMMON_OPTIONS}
-Drpm_ostree=true
-Dmalcontent=true
_build
- ninja -C _build
- .gitlab-ci/run-tests.sh
--no-suite packagekit
--no-suite fwupd
artifacts:
reports:
junit: "_build/${CI_JOB_NAME}-report.xml"
name: "gnome-software-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
when: always
paths:
- "_build/config.h"
- "_build/meson-logs"
- "_build/${CI_JOB_NAME}-report.xml"
before_script:
- export LC_ALL=C.UTF-8
- export LANG=C.UTF-8
- export SNAP_ARCH=amd64
- apt-get -y update
- apt-get install -y software-properties-common openssl
- add-apt-repository -y ppa:ubuntu-desktop/gnome-3-26
- apt-get -y update
- apt-get -y dist-upgrade
debian-stable-x86_64:
image: registry.gitlab.gnome.org/gnome/gnome-software/debian-stable:v1
build-gnome-software-snap:
stage: build
except:
- tags
only:
variables:
- $CI_COMMIT_REF_NAME == "snap-only"
script:
- meson ${MESON_COMMON_OPTIONS}
-Drpm_ostree=false
-Dmalcontent=false
_build
- ninja -C _build
- .gitlab-ci/run-tests.sh
--no-suite packagekit
--no-suite fwupd
--no-suite fedora-langpacks
artifacts:
reports:
junit: "_build/${CI_JOB_NAME}-report.xml"
name: "gnome-software-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
when: always
paths:
- "_build/config.h"
- "_build/meson-logs"
- "_build/${CI_JOB_NAME}-report.xml"
- openssl aes-256-cbc -d -in snap/.snapcraft.encrypted -out snap/.snapcraft.exported -k $KEY
- snapcraft login --with snap/.snapcraft.exported
- SNAPCRAFT_SETUP_CORE=1 snapcraft
- snapcraft push gnome-software*.snap --release edge
- snapcraft logout
- rm -f snap/.snapcraft.exported
- rm $HOME/.config/snapcraft/snapcraft.cfg
......@@ -6,6 +6,9 @@ compiled_schemas = gnome.compile_schemas()
install_data('org.gnome.software.gschema.xml',
install_dir : 'share/glib-2.0/schemas')
install_data('org.gnome.Software.desktop',
install_dir : 'share/ubuntu/applications')
if get_option('external_appstream')
# replace @libexecdir@
conf_data = configuration_data()
......
[Desktop Entry]
Name=Ubuntu Software
Comment=Add, remove or update software on this computer
# Translators: Do NOT translate or transliterate this text (this is an icon file name)!
Icon=ubuntusoftware
Exec=gnome-software %U
Terminal=false
Type=Application
Categories=GNOME;GTK;System;PackageManager;
# Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
Keywords=Updates;Upgrade;Sources;Repositories;Preferences;Install;Uninstall;Program;Software;App;Store;
StartupNotify=true
MimeType=x-scheme-handler/appstream;x-scheme-handler/apt;x-scheme-handler/snap;
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=gnome-software
X-GNOME-Bugzilla-Component=gnome-software
X-GNOME-UsesNotifications=true
DBusActivatable=true
X-Ubuntu-Gettext-Domain=gnome-software
......@@ -67,6 +67,7 @@ typedef struct
gchar *summary_missing;
gchar *description;
GsAppQuality description_quality;
gboolean description_markup;
GPtrArray *screenshots;
GPtrArray *categories;
GPtrArray *key_colors;
......@@ -78,6 +79,7 @@ typedef struct
gchar *origin;
gchar *origin_appstream;
gchar *origin_hostname;
GPtrArray *permissions_;
gchar *update_version;
gchar *update_version_ui;
gchar *update_details;
......@@ -483,6 +485,18 @@ gs_app_to_string_append (GsApp *app, GString *str)
gs_app_kv_lpad (str, "icon-filename",
as_icon_get_filename (icon));
}
for (i = 0; i < priv->permissions_->len; i++) {
GsPermission *permission;
GsPermissionValue *value;
g_autofree gchar *key = NULL;
permission = g_ptr_array_index (priv->permissions_, i);
value = gs_permission_get_value (permission);
key = g_strdup_printf ("permission-%02u", i);
gs_app_kv_printf (str, key, "[%s] %s",
gs_permission_get_label (permission),
value ? gs_permission_value_get_label (value) : "(unset)");
}
if (priv->match_value != 0)
gs_app_kv_printf (str, "match-value", "%05x", priv->match_value);
if (priv->priority != 0)
......@@ -2147,6 +2161,45 @@ gs_app_set_description (GsApp *app, GsAppQuality quality, const gchar *descripti
_g_set_str (&priv->description, description);
}
/**
* gs_app_get_description_markup:
* @app: a #GsApp
*
* Gets if the description uses markup.
*
* Returns: %TRUE if the description is formatted using markup.
*
* Since: 3.32
**/
gboolean
gs_app_get_description_markup (GsApp *app)
{
GsAppPrivate *priv = gs_app_get_instance_private (app);
g_return_val_if_fail (GS_IS_APP (app), FALSE);
return priv->description_markup;
}
/**
* gs_app_set_description_markup:
* @app: a #GsApp
* @use_markup: if the description uses markup
*
* Sets the description is formatted using markup.
*
* Since: 3.32
**/
void
gs_app_set_description_markup (GsApp *app, gboolean use_markup)
{
GsAppPrivate *priv = gs_app_get_instance_private (app);
g_autoptr(GMutexLocker) locker = NULL;
g_return_if_fail (GS_IS_APP (app));
locker = g_mutex_locker_new (&priv->mutex);
priv->description_markup = use_markup;
}
/**
* gs_app_get_url:
* @app: a #GsApp
......@@ -2577,6 +2630,46 @@ gs_app_set_origin_hostname (GsApp *app, const gchar *origin_hostname)
priv->origin_hostname = g_strdup (origin_hostname);
}
/**
* gs_app_add_permission:
* @app: a #GsApp
* @permission: a #GsPermission
*
* Adds a permission to the applicaton.
*
* Since: 3.26
**/
void
gs_app_add_permission (GsApp *app, GsPermission *permission)
{
GsAppPrivate *priv = gs_app_get_instance_private (app);
g_return_if_fail (GS_IS_APP (app));
g_return_if_fail (GS_IS_PERMISSION (permission));
g_ptr_array_add (priv->permissions_, g_object_ref (permission));
}
/**
* gs_app_get_permissions_:
* @app: a #GsApp
*
* Gets the list of permissions.
*
* Returns: (element-type GsPermission) (transfer none): a list
*
* Since: 3.26
**/
GPtrArray *
gs_app_get_permissions_ (GsApp *app)
{
GsAppPrivate *priv = gs_app_get_instance_private (app);
g_return_val_if_fail (GS_IS_APP (app), NULL);
return priv->permissions_;
}
/**
* gs_app_add_screenshot:
* @app: a #GsApp
......@@ -4184,6 +4277,7 @@ gs_app_dispose (GObject *object)
g_clear_pointer (&priv->reviews, g_ptr_array_unref);
g_clear_pointer (&priv->provides, g_ptr_array_unref);
g_clear_pointer (&priv->icons, g_ptr_array_unref);
g_clear_pointer (&priv->permissions_, g_ptr_array_unref);
G_OBJECT_CLASS (gs_app_parent_class)->dispose (object);
}
......@@ -4370,6 +4464,7 @@ gs_app_init (GsApp *app)
priv->reviews = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
priv->provides = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
priv->icons = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
priv->permissions_ = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
priv->metadata = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
......
......@@ -13,6 +13,8 @@
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <appstream-glib.h>
#include "gs-permission.h"
G_BEGIN_DECLS
#define GS_TYPE_APP (gs_app_get_type ())
......@@ -238,6 +240,9 @@ const gchar *gs_app_get_description (GsApp *app);
void gs_app_set_description (GsApp *app,
GsAppQuality quality,
const gchar *description);
gboolean gs_app_get_description_markup (GsApp *app);
void gs_app_set_description_markup (GsApp *app,
gboolean use_markup);
const gchar *gs_app_get_url (GsApp *app,
AsUrlKind kind);
void gs_app_set_url (GsApp *app,
......@@ -265,6 +270,9 @@ void gs_app_set_origin_appstream (GsApp *app,
const gchar *gs_app_get_origin_hostname (GsApp *app);
void gs_app_set_origin_hostname (GsApp *app,
const gchar *origin_hostname);
GPtrArray *gs_app_get_permissions_ (GsApp *app);
void gs_app_add_permission (GsApp *app,
GsPermission *permission);
GPtrArray *gs_app_get_screenshots (GsApp *app);
void gs_app_add_screenshot (GsApp *app,
AsScreenshot *screenshot);
......
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2017 Canonical Ltd.
*
* Licensed under the GNU General Public License Version 2
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include <glib/gi18n.h>
#include "gs-permission-value.h"
struct _GsPermissionValue
{
GObject parent_instance;
gchar *label;
GHashTable *metadata; /* utf8: utf8 */
};
G_DEFINE_TYPE (GsPermissionValue, gs_permission_value, G_TYPE_OBJECT)
/**
* gs_permission_value_get_metadata_item:
* @value: a #GsPermissionValue
* @key: a string
*
* Gets some metadata from a permission value object.
* It is left for the the plugin to use this method as required, but a
* typical use would be to retrieve an ID for this permission value.
*
* Returns: A string value, or %NULL for not found
*/
const gchar *
gs_permission_value_get_metadata_item (GsPermissionValue *value, const gchar *key)
{
g_return_val_if_fail (GS_IS_PERMISSION_VALUE (value), NULL);
g_return_val_if_fail (key != NULL, NULL);
return g_hash_table_lookup (value->metadata, key);
}
/**
* gs_permission_value_add_metadata:
* @value: a #GsPermissionValue
* @key: a string
* @value: a string
*
* Adds metadata to the permission object.
* It is left for the the plugin to use this method as required, but a
* typical use would be to store an ID for this permission.
*/
void
gs_permission_value_add_metadata (GsPermissionValue *value, const gchar *key, const gchar *val)
{
g_return_if_fail (GS_IS_PERMISSION_VALUE (value));
g_hash_table_insert (value->metadata, g_strdup (key), g_strdup (val));
}
/**
* gs_permission_value_get_label:
* @permission: a #GsPermissionValue
*
* Get the label for this permission.
*
* Returns: a label string.
*/
const gchar *
gs_permission_value_get_label (GsPermissionValue *value)
{
g_return_val_if_fail (GS_IS_PERMISSION_VALUE (value), NULL);
return value->label;
}
static void
gs_permission_value_finalize (GObject *object)
{
GsPermissionValue *value = GS_PERMISSION_VALUE (object);
g_free (value->label);
g_hash_table_unref (value->metadata);
G_OBJECT_CLASS (gs_permission_value_parent_class)->finalize (object);
}
static void
gs_permission_value_class_init (GsPermissionValueClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = gs_permission_value_finalize;
}
static void
gs_permission_value_init (GsPermissionValue *value)
{
value->metadata = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, g_free);
}
GsPermissionValue *
gs_permission_value_new (const gchar *label)
{
GsPermissionValue *value;
value = g_object_new (GS_TYPE_PERMISSION_VALUE, NULL);
value->label = g_strdup (label);
return GS_PERMISSION_VALUE (value);
}
/* vim: set noexpandtab: */
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2017 Canonical Ltd.
*
* Licensed under the GNU General Public License Version 2
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __GS_PERMISSION_VALUE_H
#define __GS_PERMISSION_VALUE_H
#include <glib-object.h>
G_BEGIN_DECLS
#define GS_TYPE_PERMISSION_VALUE (gs_permission_value_get_type ())
G_DECLARE_FINAL_TYPE (GsPermissionValue, gs_permission_value, GS, PERMISSION_VALUE, GObject)
GsPermissionValue *gs_permission_value_new (const gchar *label);
const gchar *gs_permission_value_get_metadata_item (GsPermissionValue *value,
const gchar *key);
void gs_permission_value_add_metadata (GsPermissionValue *value,
const gchar *key,
const gchar *val);
const gchar *gs_permission_value_get_label (GsPermissionValue *value);
G_END_DECLS
#endif /* __GS_PERMISSION_VALUE_H */
/* vim: set noexpandtab: */
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2017 Canonical Ltd.
*
* Licensed under the GNU General Public License Version 2
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include <glib/gi18n.h>
#include "gs-permission.h"
struct _GsPermission
{
GObject parent_instance;
gchar *label;
GPtrArray *values;
GsPermissionValue *value;
GHashTable *metadata; /* utf8: utf8 */
};
enum {
PROP_0,
PROP_VALUE,
PROP_LAST
};
G_DEFINE_TYPE (GsPermission, gs_permission, G_TYPE_OBJECT)
typedef struct {
GsPermission *permission;
gchar *property_name;
} PermissionNotifyData;
static gboolean
notify_idle_cb (gpointer data)
{
PermissionNotifyData *notify_data = data;
g_object_notify (G_OBJECT (notify_data->permission),
notify_data->property_name);
g_object_unref (notify_data->permission);
g_free (notify_data->property_name);
g_free (notify_data);
return G_SOURCE_REMOVE;
}
static void
gs_permission_queue_notify (GsPermission *permission, const gchar *property_name)
{
PermissionNotifyData *notify_data;
notify_data = g_new (PermissionNotifyData, 1);
notify_data->permission = g_object_ref (permission);
notify_data->property_name = g_strdup (property_name);
g_idle_add (notify_idle_cb, notify_data);
}
/**
* gs_permission_get_metadata_item:
* @permission: a #GsPermission
* @key: a string
*
* Gets some metadata from a permission object.
* It is left for the the plugin to use this method as required, but a
* typical use would be to retrieve an ID for this permission.
*
* Returns: A string value, or %NULL for not found
*/
const gchar *
gs_permission_get_metadata_item (GsPermission *permission, const gchar *key)
{
g_return_val_if_fail (GS_IS_PERMISSION (permission), NULL);
g_return_val_if_fail (key != NULL, NULL);
return g_hash_table_lookup (permission->metadata, key);
}
/**
* gs_permission_add_metadata:
* @permission: a #GsPermission
* @key: a string
* @value: a string
*
* Adds metadata to the permission object.
* It is left for the the plugin to use this method as required, but a
* typical use would be to store an ID for this permission.
*/
void
gs_permission_add_metadata (GsPermission *permission, const gchar *key, const gchar *value)
{
g_return_if_fail (GS_IS_PERMISSION (permission));
g_hash_table_insert (permission->metadata, g_strdup (key), g_strdup (value));
}
/**
* gs_permission_get_label:
* @permission: a #GsPermission
*
* Get the label for this permission.
*
* Returns: a label string.
*/
const gchar *
gs_permission_get_label (GsPermission *permission)
{
g_return_val_if_fail (GS_IS_PERMISSION (permission), NULL);
return permission->label;
}
/**
* gs_permission_add_value:
* @permission: a #GsPermission
* @value: a #GsPermissionValue
*
* Add a possible values for this permission.
*/
void
gs_permission_add_value (GsPermission *permission, GsPermissionValue *value)
{
g_return_if_fail (GS_IS_PERMISSION (permission));
g_ptr_array_add (permission->values, g_object_ref (value));
}
/**
* gs_permission_get_values:
* @permission: a #GsPermission
*
* Get the possible values for this permission.
*
* Returns: (element-type GsPermissionValue) (transfer none): a list
*/
GPtrArray *
gs_permission_get_values (GsPermission *permission)
{
g_return_val_if_fail (GS_IS_PERMISSION (permission), NULL);
return permission->values;
}
/**
* gs_permission_get_value:
* @permission: a #GsPermission
*
* Get the value for this permission.
*
* Returns: a %GsPermissionValue or %NULL.
*/
GsPermissionValue *
gs_permission_get_value (GsPermission *permission)
{
g_return_val_if_fail (GS_IS_PERMISSION (permission), NULL);
return permission->value;
}
/**
* gs_permission_set_value:
* @permission: a #GsPermission
* @value: a #GsPermissionValue to set for this permission
*
* Set the value of this permission.
*/
void
gs_permission_set_value (GsPermission *permission, GsPermissionValue *value)
{
g_return_if_fail (GS_IS_PERMISSION (permission));
if (permission->value == value)
return;
g_set_object (&permission->value, value);
gs_permission_queue_notify (permission, "value");
}
static void
gs_permission_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
{
GsPermission *permission = GS_PERMISSION (object);
switch (prop_id) {
case PROP_VALUE:
g_value_set_object (value, permission->value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gs_permission_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
{
GsPermission *permission = GS_PERMISSION (object);
switch (prop_id) {
case PROP_VALUE:
gs_permission_set_value (permission, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gs_permission_dispose (GObject *object)
{
GsPermission *permission = GS_PERMISSION (object);
g_clear_pointer (&permission->values, g_ptr_array_unref);
g_clear_object (&permission->value);
G_OBJECT_CLASS (gs_permission_parent_class)->dispose (object);
}
static void
gs_permission_finalize (GObject *object)
{
GsPermission *permission = GS_PERMISSION (object);
g_free (permission->label);
g_hash_table_unref (permission->metadata);
G_OBJECT_CLASS (gs_permission_parent_class)->finalize (object);
}
static void
gs_permission_class_init (GsPermissionClass *klass)
{
GParamSpec *pspec;
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = gs_permission_dispose;
object_class->finalize = gs_permission_finalize;
object_class->get_property = gs_permission_get_property;
object_class->set_property = gs_permission_set_property;
pspec = g_param_spec_object ("value", NULL, NULL,
GS_TYPE_PERMISSION,
G_PARAM_READWRITE);
g_object_class_install_property (object_class, PROP_VALUE, pspec);
}
static void
gs_permission_init (GsPermission *permission)
{
permission->metadata = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, g_free);
permission->values = g_ptr_array_new_with_free_func (g_object_unref);
}
GsPermission *
gs_permission_new (const gchar *label)
{
GsPermission *permission;
permission = g_object_new (GS_TYPE_PERMISSION, NULL);
permission->label = g_strdup (label);
return GS_PERMISSION (permission);
}
/* vim: set noexpandtab: */
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2017 Canonical Ltd.
*
* Licensed under the GNU General Public License Version 2
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __GS_PERMISSION_H
#define __GS_PERMISSION_H
#include <glib-object.h>
#include "gs-permission-value.h"
G_BEGIN_DECLS
#define GS_TYPE_PERMISSION (gs_permission_get_type ())
G_DECLARE_FINAL_TYPE (GsPermission, gs_permission, GS, PERMISSION, GObject)
GsPermission *gs_permission_new (const gchar *label);
const gchar *gs_permission_get_metadata_item (GsPermission *permission,
const gchar *key);
void gs_permission_add_metadata (GsPermission *permission,
const gchar *key,
const gchar *value);
const gchar *gs_permission_get_label (GsPermission *permission);
void gs_permission_add_value (GsPermission *permission,
GsPermissionValue *value);
GPtrArray *gs_permission_get_values (GsPermission *permission);
GsPermissionValue *gs_permission_get_value (GsPermission *permission);
void gs_permission_set_value (GsPermission *permission,
GsPermissionValue *value);
G_END_DECLS
#endif /* __GS_PERMISSION_H */
/* vim: set noexpandtab: */
......@@ -36,6 +36,7 @@ GFile *gs_plugin_job_get_file (GsPluginJob *self);
GsPlugin *gs_plugin_job_get_plugin (GsPluginJob *self);
GsCategory *gs_plugin_job_get_category (GsPluginJob *self);
AsReview *gs_plugin_job_get_review (GsPluginJob *self);
GsPermission *gs_plugin_job_get_permission (GsPluginJob *self);
gchar *gs_plugin_job_to_string (GsPluginJob *self);
void gs_plugin_job_set_action (GsPluginJob *self,
GsPluginAction action);
......
......@@ -33,6 +33,7 @@ struct _GsPluginJob
GFile *file;
GsCategory *category;
AsReview *review;
GsPermission *permission;
gint64 time_created;
};
......@@ -52,6 +53,7 @@ enum {
PROP_REVIEW,
PROP_MAX_RESULTS,
PROP_TIMEOUT,
PROP_PERMISSION,
PROP_LAST
};
......@@ -111,6 +113,9 @@ gs_plugin_job_to_string (GsPluginJob *self)
g_autofree gchar *path = g_file_get_path (self->file);
g_string_append_printf (str, " with file=%s", path);
}
if (self->permission != NULL) {
g_string_append_printf (str, " with permission=%s", gs_permission_get_label (self->permission));
}
if (self->plugin != NULL) {
g_string_append_printf (str, " on plugin=%s",
gs_plugin_get_name (self->plugin));
......@@ -399,6 +404,20 @@ gs_plugin_job_get_review (GsPluginJob *self)
return self->review;
}
void
gs_plugin_job_set_permission (GsPluginJob *self, GsPermission *permission)
{
g_return_if_fail (GS_IS_PLUGIN_JOB (self));
g_set_object (&self->permission, permission);
}
GsPermission *
gs_plugin_job_get_permission (GsPluginJob *self)
{
g_return_val_if_fail (GS_IS_PLUGIN_JOB (self), NULL);
return self->permission;
}
static void
gs_plugin_job_get_property (GObject *obj, guint prop_id, GValue *value, GParamSpec *pspec)
{
......@@ -447,6 +466,9 @@ gs_plugin_job_get_property (GObject *obj, guint prop_id, GValue *value, GParamSp
case PROP_TIMEOUT:
g_value_set_uint (value, self->timeout);
break;
case PROP_PERMISSION:
g_value_set_object (value, self->permission);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
break;
......@@ -501,6 +523,9 @@ gs_plugin_job_set_property (GObject *obj, guint prop_id, const GValue *value, GP
case PROP_TIMEOUT:
gs_plugin_job_set_timeout (self, g_value_get_uint (value));
break;
case PROP_PERMISSION:
gs_plugin_job_set_permission (self, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
break;
......@@ -518,6 +543,7 @@ gs_plugin_job_finalize (GObject *obj)
g_clear_object (&self->plugin);
g_clear_object (&self->category);
g_clear_object (&self->review);
g_clear_object (&self->permission);
G_OBJECT_CLASS (gs_plugin_job_parent_class)->finalize (obj);
}
......@@ -602,6 +628,11 @@ gs_plugin_job_class_init (GsPluginJobClass *klass)
0, G_MAXUINT, 60,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
g_object_class_install_property (object_class, PROP_TIMEOUT, pspec);
pspec = g_param_spec_object ("permission", NULL, NULL,
GS_TYPE_PERMISSION,
G_PARAM_READWRITE);
g_object_class_install_property (object_class, PROP_PERMISSION, pspec);
}
static void
......
......@@ -12,6 +12,7 @@
#include "gs-app-list-private.h"
#include "gs-category.h"
#include "gs-plugin-types.h"
#include "gs-permission.h"
G_BEGIN_DECLS
......@@ -51,6 +52,8 @@ void gs_plugin_job_set_category (GsPluginJob *self,
GsCategory *category);
void gs_plugin_job_set_review (GsPluginJob *self,
AsReview *review);
void gs_plugin_job_set_permission (GsPluginJob *self,
GsPermission *permission);
#define gs_plugin_job_newv(a,...) GS_PLUGIN_JOB(g_object_new(GS_TYPE_PLUGIN_JOB, "action", a, __VA_ARGS__))
......
......@@ -124,6 +124,11 @@ typedef gboolean (*GsPluginActionFunc) (GsPlugin *plugin,
GsApp *app,
GCancellable *cancellable,
GError **error);
typedef gboolean (*GsPluginSetPermissionFunc) (GsPlugin *plugin,
GsApp *app,
GsPermission *permission,
GCancellable *cancellable,
GError **error);
typedef gboolean (*GsPluginReviewFunc) (GsPlugin *plugin,
GsApp *app,
AsReview *review,
......@@ -592,6 +597,14 @@ gs_plugin_loader_call_vfunc (GsPluginLoaderHelper *helper,
ret = plugin_func (plugin, app, cancellable, &error_local);
}
break;
case GS_PLUGIN_ACTION_SET_PERMISSION:
{
GsPluginSetPermissionFunc plugin_func = func;
ret = plugin_func (plugin, app,
gs_plugin_job_get_permission (helper->plugin_job),
cancellable, &error_local);
}
break;
case GS_PLUGIN_ACTION_REVIEW_SUBMIT:
case GS_PLUGIN_ACTION_REVIEW_UPVOTE:
case GS_PLUGIN_ACTION_REVIEW_DOWNVOTE:
......
......@@ -127,6 +127,7 @@ typedef enum {
* @GS_PLUGIN_REFINE_FLAGS_REQUIRE_DEVELOPER_NAME: Require developer name
* @GS_PLUGIN_REFINE_FLAGS_REQUIRE_KUDOS: Require kudos
* @GS_PLUGIN_REFINE_FLAGS_REQUIRE_CONTENT_RATING: Require content rating
* @GS_PLUGIN_REFINE_FLAGS_REQUIRE_CHANGELOG: Require the changelog
*
* The refine flags.
**/
......@@ -163,6 +164,7 @@ typedef enum {
#define GS_PLUGIN_REFINE_FLAGS_REQUIRE_DEVELOPER_NAME ((guint64) 1 << 29)
#define GS_PLUGIN_REFINE_FLAGS_REQUIRE_KUDOS ((guint64) 1 << 30)
#define GS_PLUGIN_REFINE_FLAGS_REQUIRE_CONTENT_RATING ((guint64) 1 << 31)
#define GS_PLUGIN_REFINE_FLAGS_REQUIRE_CHANGELOG ((guint64) 1 << 32)
typedef guint64 GsPluginRefineFlags;
/**
......@@ -227,6 +229,7 @@ typedef enum {
* @GS_PLUGIN_ACTION_DOWNLOAD: Download an application
* @GS_PLUGIN_ACTION_GET_ALTERNATES: Get the alternates for a specific application
* @GS_PLUGIN_ACTION_GET_LANGPACKS: Get appropriate language pack
* @GS_PLUGIN_ACTION_SET_PERMISSION: Set app permission
*
* The plugin action.
**/
......@@ -272,6 +275,7 @@ typedef enum {
GS_PLUGIN_ACTION_DOWNLOAD,
GS_PLUGIN_ACTION_GET_ALTERNATES,
GS_PLUGIN_ACTION_GET_LANGPACKS,
GS_PLUGIN_ACTION_SET_PERMISSION,
/*< private >*/
GS_PLUGIN_ACTION_LAST
} GsPluginAction;
......
......@@ -24,6 +24,7 @@
#include "gs-app.h"
#include "gs-app-list.h"
#include "gs-category.h"
#include "gs-permission.h"
G_BEGIN_DECLS
......@@ -745,6 +746,24 @@ gboolean gs_plugin_app_upgrade_trigger (GsPlugin *plugin,
GCancellable *cancellable,
GError **error);
/**
* gs_plugin_app_set_permission:
* @plugin: a #GsPlugin
* @app: a #GsApp
* @permission: a #GsPermission to set
* @cancellable: a #GCancellable, or %NULL
* @error: a #GError, or %NULL
*
* Set an app permission.
*
* Returns: %TRUE for success or if not relevant
**/
gboolean gs_plugin_app_set_permission (GsPlugin *plugin,
GsApp *app,
GsPermission *permission,
GCancellable *cancellable,
GError **error);
/**
* gs_plugin_review_submit:
* @plugin: a #GsPlugin
......
......@@ -1604,6 +1604,8 @@ gs_plugin_action_to_function_name (GsPluginAction action)
return "gs_plugin_add_alternates";
if (action == GS_PLUGIN_ACTION_GET_LANGPACKS)
return "gs_plugin_add_langpacks";
if (action == GS_PLUGIN_ACTION_SET_PERMISSION)
return "gs_plugin_app_set_permission";
return NULL;
}
......@@ -1700,6 +1702,8 @@ gs_plugin_action_to_string (GsPluginAction action)
return "get-alternates";
if (action == GS_PLUGIN_ACTION_GET_LANGPACKS)
return "get-langpacks";
if (action == GS_PLUGIN_ACTION_SET_PERMISSION)
return "set-permission";
return NULL;
}
......@@ -1796,6 +1800,8 @@ gs_plugin_action_from_string (const gchar *action)
return GS_PLUGIN_ACTION_GET_ALTERNATES;
if (g_strcmp0 (action, "get-langpacks") == 0)
return GS_PLUGIN_ACTION_GET_LANGPACKS;
if (g_strcmp0 (action, "set-permission") == 0)
return GS_PLUGIN_ACTION_SET_PERMISSION;
return GS_PLUGIN_ACTION_UNKNOWN;
}
......
......@@ -42,6 +42,8 @@ install_headers([
'gs-category.h',
'gs-metered.h',
'gs-os-release.h',
'gs-permission.h',
'gs-permission-value.h',
'gs-plugin.h',
'gs-plugin-event.h',
'gs-plugin-types.h',
......@@ -83,6 +85,8 @@ libgnomesoftware = static_library(
'gs-ioprio.h',
'gs-metered.c',
'gs-os-release.c',
'gs-permission.c',
'gs-permission-value.c',
'gs-plugin.c',
'gs-plugin-event.c',
'gs-plugin-job.c',
......
......@@ -186,7 +186,8 @@ if get_option('gudev')
endif
if get_option('snap')
snap = dependency('snapd-glib', version : '>= 1.50')
snap = dependency('snapd-glib', version : '>= 1.57')
conf.set('HAVE_SNAP', 1)
endif
gnome = import('gnome')
......
......@@ -299,6 +299,7 @@ gs_plugin_odrs_parse_reviews (GsPlugin *plugin,
gssize data_len,
GError **error)
{
GsPluginData *priv = gs_plugin_get_data (plugin);
JsonArray *json_reviews;
JsonNode *json_root;
guint i;
......@@ -365,6 +366,14 @@ gs_plugin_odrs_parse_reviews (GsPlugin *plugin,
return NULL;
}
if (!json_object_has_member (json_item, "distro")) {
g_debug ("Ignoring review without distro set");
continue;
} else if (g_strcmp0 (json_object_get_string_member (json_item, "distro"), priv->distro) != 0) {
g_debug ("Ignoring review from distro %s", json_object_get_string_member (json_item, "distro"));
continue;
}
/* create review */
review = gs_plugin_odrs_parse_review_object (plugin,
json_item);
......
......@@ -112,6 +112,9 @@ gs_plugin_download (GsPlugin *plugin,
{
g_autoptr(GsAppList) list_tmp = gs_app_list_new ();
/* In Ubuntu we're using Update Manager for this, for now (LP: #1775226) */
return TRUE;
/* add any packages */
for (guint i = 0; i < gs_app_list_length (list); i++) {
GsApp *app = gs_app_list_index (list, i);
......
......@@ -591,6 +591,9 @@ gs_plugin_add_updates (GsPlugin *plugin,
g_autoptr(PkResults) results = NULL;
g_autoptr(GPtrArray) array = NULL;
/* In Ubuntu we're using Update Manager for this, for now. */
return TRUE;
/* do sync call */
gs_plugin_status_update (plugin, NULL, GS_PLUGIN_STATUS_WAITING);
g_mutex_lock (&priv->task_mutex);
......
......@@ -265,6 +265,9 @@ gs_plugin_update (GsPlugin *plugin,
GCancellable *cancellable,
GError **error)
{
/* In Ubuntu we're using Update Manager for this, for now. */
return TRUE;
/* any are us? */
for (guint i = 0; i < gs_app_list_length (list); i++) {
GsApp *app = gs_app_list_index (list, i);
......
<svg width="96" height="96" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><path d="M11.334 17.02l37.077 46.978-28.768 22.735C7.733 77.998 0 63.902 0 48a47.809 47.809 0 0 1 11.334-30.98z" id="a"/><path d="M92.245 29.357A47.85 47.85 0 0 1 96 48c0 18.733-10.73 34.96-26.38 42.867L48.41 63.997l43.834-34.64z" id="b"/><path d="M19.643 86.733l28.768-22.735 21.208 26.87A47.799 47.799 0 0 1 48 96a47.784 47.784 0 0 1-28.357-9.267z" id="c"/><path d="M92.245 29.357l-43.834 34.64-37.077-46.976C20.14 6.61 33.298 0 48 0c19.898 0 36.968 12.107 44.245 29.357z" id="d"/></defs><g fill="none" fill-rule="evenodd"><use fill="#DCDCDC" xlink:href="#a"/><use fill="#E1E1E1" xlink:href="#b"/><use fill="#D9D9D9" xlink:href="#c"/><use fill="#E6E6E6" xlink:href="#d"/></g></svg>
\ No newline at end of file
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gnome/Software/Snap">
<file>default-snap-icon.svg</file>
</gresource>
</gresources>
cargs = ['-DG_LOG_DOMAIN="GsPluginSnap"']
resources_src = gnome.compile_resources(
'gs-plugin-snap-resources',
'gs-plugin-snap.gresource.xml',
source_dir : '.',
c_name : 'gs_plugin_snap'
)
shared_module(
'gs_plugin_snap',
resources_src,
sources : [
'gs-plugin-snap.c'
],
......
data/appdata/org.gnome.Software.appdata.xml.in
data/org.gnome.Software.desktop
data/org.gnome.software.external-appstream.policy.in.in
data/org.gnome.software.gschema.xml
src/gnome-software-local-file.desktop.in
......@@ -38,6 +39,7 @@ src/gs-origin-popover-row.ui
src/gs-overview-page.c
src/gs-overview-page.ui
src/gs-page.c
src/gs-permission-dialog.ui
lib/gs-plugin-loader.c
src/gs-popular-tile.c
src/gs-popular-tile.ui
......@@ -58,6 +60,10 @@ src/gs-search-page.c
src/gs-search-page.ui
src/gs-shell.c
src/gs-shell-search-provider.c
src/gs-snap-store-login-dialog.c
src/gs-snap-store-login-dialog.ui
src/gs-snap-store-logout-dialog.c
src/gs-snap-store-logout-dialog.ui
src/gs-star-widget.ui
src/gs-summary-tile.c
src/gs-summary-tile.ui
......
This diff is collapsed.
#!/bin/sh
if test "$1" = "classic"; then
shift
case $SNAP_ARCH in
amd64)
TRIPLET="x86_64-linux-gnu"
;;
armhf)
TRIPLET="arm-linux-gnueabihf"
;;
arm64)
TRIPLET="aarch64-linux-gnu"
;;
*)
TRIPLET="$(uname -p)-linux-gnu"
;;
esac
export LD_LIBRARY_PATH=$SNAP/usr/lib:$SNAP/usr/lib/$TRIPLET:$SNAP/lib/$TRIPLET:$SNAP/usr/lib/$TRIPLET/gs-plugins-11
fi
exec ${SNAP}/bin/desktop-launch $@
# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
#
# Copyright (C) 2017 Canonical Ltd
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3 as
# published by the Free Software Foundation.
#
# 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 <http://www.gnu.org/licenses/>.
"""The meson plugin is useful for building meson based parts.
Meson based projects are projects that have a meson.build that drives the
build.
This plugin always runs 'meson snapbuild' followed by 'ninja' and
'ninja install'.
Additionally, this plugin uses the following plugin-specific keywords:
- meson-parameters:
(list of strings)
Pass the given parameters to the meson command.
"""
import os
import snapcraft
class MesonPlugin(snapcraft.BasePlugin):
@classmethod
def schema(cls):
schema = super().schema()
schema['properties']['meson-parameters'] = {
'type': 'array',
'minitems': 1,
'uniqueItems': True,
'items': {
'type': 'string',
},
'default': [],
}
return schema
@classmethod
def get_build_properties(cls):
return ['meson-parameters']
def __init__(self, name, options, project):
super().__init__(name, options, project)
self.snapbuildname = 'snapbuild'
self.mesonbuilddir = os.path.join(self.builddir, self.snapbuildname)
self.build_packages.append('meson')
self.build_packages.append('ninja-build')
def build(self):
super().build()
self._run_meson()
self._run_ninja_build_default()
self._run_ninja_install()
def _run_meson(self):
os.makedirs(self.mesonbuilddir, exist_ok=True)
meson_command = ['meson']
if self.options.meson_parameters:
meson_command.extend(self.options.meson_parameters)
meson_command.append(self.snapbuildname)
env = os.environ.copy()
env['PKG_CONFIG_PATH'] = self.project.stage_dir + '/usr/lib/pkgconfig:/usr/lib/' + self.project.arch_triplet + '/pkgconfig:/usr/lib/pkgconfig'
self.run(meson_command, env=env)
def _run_ninja_build_default(self):
ninja_command = ['ninja']
env = os.environ.copy()
env['PKG_CONFIG_PATH'] = self.project.stage_dir + '/usr/lib/pkgconfig:/usr/lib/' + self.project.arch_triplet + '/pkgconfig:/usr/lib/pkgconfig'
self.run(ninja_command, env=env, cwd=self.mesonbuilddir)
def _run_ninja_install(self):
env = os.environ.copy()
env['DESTDIR'] = self.installdir
ninja_install_command = ['ninja', 'install']
self.run(ninja_install_command, env=env, cwd=self.mesonbuilddir)
name: gnome-software
version: git
summary: Application manager for GNOME
description: |
Software allows you to find and install new applications and system
extensions and remove existing installed applications.
GNOME Software showcases featured and popular applications with useful
descriptions and multiple screenshots per application.
Applications can be found either through browsing the list of categories
or by searching.
It also allows you to update your system using an offline update.
grade: stable # must be 'stable' to release into candidate/stable channels
confinement: classic
apps:
gnome-software:
command: bin/classic-launch classic ${SNAP}/usr/bin/gnome-software
desktop: usr/share/applications/org.gnome.Software.desktop
parts:
gnome-3-26:
plugin: nil
prepare: |
apt-get -y update
apt-get install -y software-properties-common
add-apt-repository -y ppa:ubuntu-desktop/gnome-3-26
apt-get -y update
apt-get -y dist-upgrade
desktop-gtk3:
after: [gnome-3-26]
iso-codes:
after: [desktop-gtk3]
source: https://ftp.osuosl.org/pub/blfs/conglomeration/iso-codes/iso-codes-3.77.tar.xz
plugin: autotools
configflags: [--prefix=/snap/gnome-software/current/usr]
organize:
snap/gnome-software/current/usr: usr
build-attributes: ['no-system-libraries']
build-packages:
- gettext
- python3
gnome-desktop:
after: [iso-codes]
source: https://git.gnome.org/browse/gnome-desktop
source-type: git
source-tag: 3.26.2
plugin: autotools
prepare:
sed -i.bak -e 's|.*ISO_CODES_PREFIX=.*|ISO_CODES_PREFIX=/snap/gnome-software/current/usr|g' configure.ac
configflags:
- --prefix=/usr
- --disable-date-in-gnome-version
- --with-gnome-distributor=Ubuntu
- --disable-debug-tools
- --disable-desktop-docs
- --enable-introspection=no
organize:
snap/gnome-software/current/usr: usr
build-attributes: ['no-system-libraries']
build-packages:
- libglib2.0-dev
- gnome-common
- intltool
- gnome-pkg-tools
- gtk-doc-tools
- docbook-xml
- libx11-dev
- xkb-data
- libgdk-pixbuf2.0-dev
- libgl1-mesa-dev
- libgtk-3-dev
- libxml2-dev
- libglib2.0-doc
- libgtk-3-doc
- libseccomp-dev
- libudev-dev
- gobject-introspection
- libgirepository1.0-dev
- gsettings-desktop-schemas-dev
- yelp-tools
snapd-glib:
after: [gnome-3-26]
source: https://github.com/snapcore/snapd-glib
source-type: git
plugin: autotools
configflags: [--prefix=/usr, --disable-glibtest]
organize:
snap/gnome-software/current/usr: usr
build-attributes: ['no-system-libraries']
build-packages:
- intltool
- libgirepository1.0-dev
- libglib2.0-dev
- libjson-glib-dev
- libpolkit-gobject-1-dev
- libsoup2.4-dev
- valac
gnome-software:
build-attributes: [no-system-libraries]
after: [snapd-glib, gnome-desktop]
source: .
source-type: git
prepare:
sed -i.bak -e 's|Icon=org.gnome.Software$|Icon=${SNAP}/meta/gui/org.gnome.Software.png|g' src/org.gnome.Software.desktop.in
install: |
mkdir -p $SNAPCRAFT_PART_INSTALL/meta/gui/
cp data/icons/hicolor/256x256/org.gnome.Software.png $SNAPCRAFT_PART_INSTALL/meta/gui/
cp snapbuild/src/org.gnome.Software.desktop $SNAPCRAFT_PART_INSTALL/meta/gui/
plugin: meson
meson-parameters:
- --prefix=/snap/gnome-software/current/usr
- -Denable-gnome-desktop=true
- -Denable-odrs=true
- -Denable-ostree=false
- -Denable-packagekit=true
- -Denable-rpm=false
- -Denable-snap=true
- -Denable-fwupd=false
- -Denable-flatpak=false
- -Denable-limba=false
- -Denable-ubuntu-reviews=true
- -Denable-tests=false
- -Denable-gspell=false
organize:
snap/gnome-software/current/usr: usr
build-packages:
- appstream
- appstream-util
- docbook-xsl
- gsettings-desktop-schemas-dev
- gtk-doc-tools
- intltool
- libappstream-glib-dev
#- libfwupd-dev
- libglib2.0-bin
- libglib2.0-dev
- libgtk-3-dev
#- libgspell-1-dev
- libgudev-1.0-dev
- libjson-glib-dev
- liboauth-dev
- libpackagekit-glib2-dev
- libpolkit-gobject-1-dev
- libsecret-1-dev
- libsoup2.4-dev
- libsqlite3-dev
- libxml2-utils
- meson
- pkg-config
- valgrind
- xsltproc
stage-packages:
- libappstream-glib8
- libsecret-1-0
- appstream
- packagekit
#- libgspell-1-1
#- libfwupd2
- libgudev-1.0-0
- liboauth0
- hicolor-icon-theme
- humanity-icon-theme
- light-themes
- ubuntu-mono
- ubuntu-settings
magic:
after: [gnome-software]
plugin: nil
stage-packages:
- libglib2.0-0
- libglib2.0-bin
- shared-mime-info
install: |
set -eux
glib-compile-schemas $SNAPCRAFT_PART_INSTALL/usr/share/glib-2.0/schemas
update-mime-database $SNAPCRAFT_PART_INSTALL/usr/share/mime
classic-launch:
plugin: dump
source: ./snap
organize:
classic-launch: bin/classic-launch
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" height="12px" width="12px" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 12 12"><!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title>path6490</title>
<desc>Created with Sketch.</desc>
<g id="misc" fill-rule="evenodd" fill="none">
<g id="Artboard" fill-rule="nonzero" fill="#82BEA0" transform="translate(-419 -444)">
<g id="VALIDATED--SNAPCRAFTER-ICON" transform="translate(419 444)">
<path id="path6490" d="m5.0239 0.38296l-0.4325 0.40107c-0.3507 0.32527-0.8065 0.51407-1.2846 0.53217l-0.5886 0.0222c-0.75 0.0283-1.3515 0.6298-1.3798 1.3798l-0.0222 0.5886c-0.0181 0.4781-0.2069 0.9339-0.53217 1.2846l-0.40107 0.4325c-0.51061 0.5506-0.51061 1.4016 0 1.9522l0.40107 0.4325c0.32527 0.3507 0.51407 0.8065 0.53217 1.2846l0.0222 0.5886c0.0283 0.7502 0.6298 1.3512 1.3798 1.3802l0.5886 0.022c0.4781 0.018 0.9339 0.207 1.2846 0.532l0.4325 0.401c0.5506 0.511 1.4016 0.511 1.9522 0l0.4325-0.401c0.3507-0.325 0.8065-0.514 1.2846-0.532l0.5886-0.022c0.7502-0.029 1.3512-0.63 1.3802-1.3802l0.022-0.5886c0.018-0.4781 0.207-0.9339 0.532-1.2846l0.401-0.4325c0.511-0.5506 0.511-1.4016 0-1.9522l-0.401-0.4325c-0.325-0.3507-0.514-0.8065-0.532-1.2846l-0.022-0.5886c-0.029-0.75-0.63-1.3515-1.3802-1.3798l-0.5886-0.0222c-0.4781-0.0181-0.9339-0.2069-1.2846-0.53217l-0.4325-0.40107c-0.5506-0.51061-1.4016-0.51061-1.9522 0zm3.3697 3.1711l0.8675 0.8565-4.2062 4.2411-2.316-2.3398 0.8611-0.8549 1.4549 1.4659 3.3387-3.3688z"/>
</g>
</g>
</g>
</svg>
\ No newline at end of file