summaryrefslogtreecommitdiff
path: root/libappstream-glib/as-agreement.c
diff options
context:
space:
mode:
Diffstat (limited to 'libappstream-glib/as-agreement.c')
-rw-r--r--libappstream-glib/as-agreement.c330
1 files changed, 330 insertions, 0 deletions
diff --git a/libappstream-glib/as-agreement.c b/libappstream-glib/as-agreement.c
new file mode 100644
index 0000000..8c78204
--- /dev/null
+++ b/libappstream-glib/as-agreement.c
@@ -0,0 +1,330 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2018 Richard Hughes <richard@hughsie.com>
+ *
+ * Licensed under the GNU Lesser General Public License Version 2.1
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * SECTION:as-agreement
+ * @short_description: Object representing a privacy policy
+ * @include: appstream-glib.h
+ * @stability: Unstable
+ *
+ * Agreements can be used by components to specify GDPR, EULA or other warnings.
+ *
+ * See also: #AsAgreementDetail, #AsAgreementSection
+ */
+
+#include "config.h"
+
+#include "as-node-private.h"
+#include "as-agreement-private.h"
+#include "as-agreement-section-private.h"
+#include "as-ref-string.h"
+#include "as-tag.h"
+
+typedef struct {
+ AsAgreementKind kind;
+ AsRefString *version_id;
+ GPtrArray *sections;
+} AsAgreementPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (AsAgreement, as_agreement, G_TYPE_OBJECT)
+
+#define GET_PRIVATE(o) (as_agreement_get_instance_private (o))
+
+static void
+as_agreement_finalize (GObject *object)
+{
+ AsAgreement *agreement = AS_AGREEMENT (object);
+ AsAgreementPrivate *priv = GET_PRIVATE (agreement);
+
+ if (priv->version_id != NULL)
+ as_ref_string_unref (priv->version_id);
+ g_ptr_array_unref (priv->sections);
+
+ G_OBJECT_CLASS (as_agreement_parent_class)->finalize (object);
+}
+
+static void
+as_agreement_init (AsAgreement *agreement)
+{
+ AsAgreementPrivate *priv = GET_PRIVATE (agreement);
+ priv->sections = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
+}
+
+static void
+as_agreement_class_init (AsAgreementClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = as_agreement_finalize;
+}
+
+/**
+ * as_agreement_kind_to_string:
+ * @value: the #AsAgreementKind.
+ *
+ * Converts the enumerated value to an text representation.
+ *
+ * Returns: string version of @value
+ *
+ * Since: 0.7.8
+ **/
+const gchar *
+as_agreement_kind_to_string (AsAgreementKind value)
+{
+ if (value == AS_AGREEMENT_KIND_GENERIC)
+ return "generic";
+ if (value == AS_AGREEMENT_KIND_EULA)
+ return "eula";
+ if (value == AS_AGREEMENT_KIND_PRIVACY)
+ return "privacy";
+ return "unknown";
+}
+
+/**
+ * as_agreement_kind_from_string:
+ * @value: the string.
+ *
+ * Converts the text representation to an enumerated value.
+ *
+ * Returns: a #AsAgreementKind or %AS_AGREEMENT_KIND_UNKNOWN for unknown
+ *
+ * Since: 0.7.8
+ **/
+AsAgreementKind
+as_agreement_kind_from_string (const gchar *value)
+{
+ if (g_strcmp0 (value, "generic") == 0)
+ return AS_AGREEMENT_KIND_GENERIC;
+ if (g_strcmp0 (value, "eula") == 0)
+ return AS_AGREEMENT_KIND_EULA;
+ if (g_strcmp0 (value, "privacy") == 0)
+ return AS_AGREEMENT_KIND_PRIVACY;
+ return AS_AGREEMENT_KIND_UNKNOWN;
+}
+
+/**
+ * as_agreement_get_kind:
+ * @agreement: a #AsAgreement instance.
+ *
+ * Gets the agreement kind.
+ *
+ * Returns: a string, e.g. %AS_AGREEMENT_KIND_EULA
+ *
+ * Since: 0.7.8
+ **/
+AsAgreementKind
+as_agreement_get_kind (AsAgreement *agreement)
+{
+ AsAgreementPrivate *priv = GET_PRIVATE (agreement);
+ return priv->kind;
+}
+
+/**
+ * as_agreement_set_kind:
+ * @agreement: a #AsAgreement instance.
+ * @kind: the agreement kind, e.g. %AS_AGREEMENT_KIND_EULA
+ *
+ * Sets the agreement kind.
+ *
+ * Since: 0.7.8
+ **/
+void
+as_agreement_set_kind (AsAgreement *agreement, AsAgreementKind kind)
+{
+ AsAgreementPrivate *priv = GET_PRIVATE (agreement);
+ priv->kind = kind;
+}
+
+/**
+ * as_agreement_get_version_id:
+ * @agreement: a #AsAgreement instance.
+ *
+ * Gets the agreement version_id.
+ *
+ * Returns: a string, e.g. "1.4a", or NULL
+ *
+ * Since: 0.7.8
+ **/
+const gchar *
+as_agreement_get_version_id (AsAgreement *agreement)
+{
+ AsAgreementPrivate *priv = GET_PRIVATE (agreement);
+ return priv->version_id;
+}
+
+/**
+ * as_agreement_set_version_id:
+ * @agreement: a #AsAgreement instance.
+ * @version_id: the agreement version ID, e.g. "1.4a"
+ *
+ * Sets the agreement version identifier.
+ *
+ * Since: 0.7.8
+ **/
+void
+as_agreement_set_version_id (AsAgreement *agreement, const gchar *version_id)
+{
+ AsAgreementPrivate *priv = GET_PRIVATE (agreement);
+ as_ref_string_assign_safe (&priv->version_id, version_id);
+}
+
+/**
+ * as_agreement_get_sections:
+ * @agreement: a #AsAgreement instance.
+ *
+ * Gets all the sections in the agreement.
+ *
+ * Returns: (transfer container) (element-type AsAgreementSection): array
+ *
+ * Since: 0.7.8
+ **/
+GPtrArray *
+as_agreement_get_sections (AsAgreement *agreement)
+{
+ AsAgreementPrivate *priv = GET_PRIVATE (agreement);
+ return priv->sections;
+}
+
+/**
+ * as_agreement_get_section_default:
+ * @agreement: a #AsAgreement instance.
+ *
+ * Gets the first section in the agreement.
+ *
+ * Returns: (transfer none): agreement section, or %NULL
+ *
+ * Since: 0.7.8
+ **/
+AsAgreementSection *
+as_agreement_get_section_default (AsAgreement *agreement)
+{
+ AsAgreementPrivate *priv = GET_PRIVATE (agreement);
+ if (priv->sections->len == 0)
+ return NULL;
+ return AS_AGREEMENT_SECTION (g_ptr_array_index (priv->sections, 0));
+}
+
+/**
+ * as_agreement_add_detail:
+ * @agreement: a #AsAgreement instance.
+ * @agreement_section: a #AsAgreementSection instance.
+ *
+ * Adds a section to the agreement.
+ *
+ * Since: 0.7.8
+ **/
+void
+as_agreement_add_section (AsAgreement *agreement, AsAgreementSection *agreement_section)
+{
+ AsAgreementPrivate *priv = GET_PRIVATE (agreement);
+ g_ptr_array_add (priv->sections, g_object_ref (agreement_section));
+}
+
+/**
+ * as_agreement_node_insert: (skip)
+ * @agreement: a #AsAgreement instance.
+ * @parent: the parent #GNode to use..
+ * @ctx: the #AsNodeContext
+ *
+ * Inserts the agreement into the DOM tree.
+ *
+ * Returns: (transfer none): A populated #GNode, or %NULL
+ *
+ * Since: 0.7.8
+ **/
+GNode *
+as_agreement_node_insert (AsAgreement *agreement,
+ GNode *parent,
+ AsNodeContext *ctx)
+{
+ AsAgreementPrivate *priv = GET_PRIVATE (agreement);
+ GNode *n = as_node_insert (parent, "agreement", NULL,
+ AS_NODE_INSERT_FLAG_NONE,
+ NULL);
+ if (priv->kind != AS_AGREEMENT_KIND_UNKNOWN) {
+ as_node_add_attribute (n, "type",
+ as_agreement_kind_to_string (priv->kind));
+ }
+ if (priv->version_id != NULL)
+ as_node_add_attribute (n, "version_id", priv->version_id);
+ for (guint i = 0; i < priv->sections->len; i++) {
+ AsAgreementSection *ps = g_ptr_array_index (priv->sections, i);
+ as_agreement_section_node_insert (ps, n, ctx);
+ }
+
+ return n;
+}
+
+/**
+ * as_agreement_node_parse:
+ * @agreement: a #AsAgreement instance.
+ * @node: a #GNode.
+ * @ctx: a #AsNodeContext.
+ * @error: A #GError or %NULL.
+ *
+ * Populates the object from a DOM node.
+ *
+ * Returns: %TRUE for success
+ *
+ * Since: 0.7.8
+ **/
+gboolean
+as_agreement_node_parse (AsAgreement *agreement, GNode *node,
+ AsNodeContext *ctx, GError **error)
+{
+ const gchar *tmp;
+
+ /* get ID */
+ tmp = as_node_get_attribute (node, "type");
+ if (tmp != NULL)
+ as_agreement_set_kind (agreement, as_agreement_kind_from_string (tmp));
+ tmp = as_node_get_attribute (node, "version_id");
+ if (tmp != NULL)
+ as_agreement_set_version_id (agreement, tmp);
+
+ /* get sections and details */
+ for (GNode *c = node->children; c != NULL; c = c->next) {
+ if (as_node_get_tag (c) == AS_TAG_AGREEMENT_SECTION) {
+ g_autoptr(AsAgreementSection) ps = as_agreement_section_new ();
+ if (!as_agreement_section_node_parse (ps, c, ctx, error))
+ return FALSE;
+ as_agreement_add_section (agreement, ps);
+ continue;
+ }
+ }
+ return TRUE;
+}
+
+/**
+ * as_agreement_new:
+ *
+ * Creates a new #AsAgreement.
+ *
+ * Returns: (transfer full): a #AsAgreement
+ *
+ * Since: 0.7.8
+ **/
+AsAgreement *
+as_agreement_new (void)
+{
+ AsAgreement *agreement;
+ agreement = g_object_new (AS_TYPE_AGREEMENT, NULL);
+ return AS_AGREEMENT (agreement);
+}