[recipes] Drop the libappstream-glib dependency again
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [recipes] Drop the libappstream-glib dependency again
- Date: Mon, 27 Feb 2017 23:56:18 +0000 (UTC)
commit cb1ec0ea3a31aa13f318a3235b899af8857c13a7
Author: Matthias Clasen <mclasen redhat com>
Date: Mon Feb 27 18:55:26 2017 -0500
Drop the libappstream-glib dependency again
We can just as easily do this bit of xml parsing
ourselves and save the trouble of the extra dependency.
configure.ac | 1 -
meson.build | 1 -
src/gr-appdata.c | 210 +++++++++++++++++++++++++++++++++++++++++++++---------
src/gr-appdata.h | 2 +-
src/gr-window.c | 2 +-
5 files changed, 178 insertions(+), 38 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index d7af373..5aa03cc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -139,7 +139,6 @@ dnl ***********************************************************************
PKG_CHECK_MODULES(RECIPES, [gmodule-2.0
gio-2.0 >= 2.42
gtk+-3.0 >= 3.22
- appstream-glib
$AUTOAR_DEP
$GSPELL_DEP
$CANBERRA_DEP])
diff --git a/meson.build b/meson.build
index 4de4157..e65dd1e 100644
--- a/meson.build
+++ b/meson.build
@@ -62,7 +62,6 @@ endif
deps = [ dependency('gtk+-3.0', version : '>=3.22'),
dependency('gmodule-export-2.0'),
- dependency('appstream-glib'),
autoar_dep,
gspell_dep,
canberra_dep,
diff --git a/src/gr-appdata.c b/src/gr-appdata.c
index 3f9df1b..af8b373 100644
--- a/src/gr-appdata.c
+++ b/src/gr-appdata.c
@@ -20,7 +20,8 @@
#include "config.h"
-#include <appstream-glib.h>
+#include <string.h>
+#include <stdlib.h>
#include <gr-appdata.h>
static void
@@ -30,7 +31,7 @@ release_info_free (gpointer data)
g_free (ri->version);
g_date_time_unref (ri->date);
- g_free (ri->news);
+ g_string_free (ri->news, TRUE);
g_free (ri);
}
@@ -72,51 +73,192 @@ version_between (const char *v,
return version_compare (lower, v) <= 0 && version_compare (v, upper) <= 0;
}
-GPtrArray *
-get_release_info (const char *new_version,
- const char *old_version)
+typedef struct {
+ GPtrArray *result;
+ const char *old_version;
+ const char *new_version;
+ ReleaseInfo *ri;
+ gboolean collect;
+ GString *text;
+} ParserData;
+
+static const char *
+find_attribute (const char *name,
+ const char **names,
+ const char **values)
{
- GPtrArray *news;
- g_autoptr(AsApp) app = NULL;
- GPtrArray *releases = NULL;
- unsigned int i;
- g_autofree char *file = NULL;
- g_autoptr(GError) error = NULL;
+ int i;
- file = g_build_filename (DATADIR, "appdata", "org.gnome.Recipes.appdata.xml", NULL);
+ for (i = 0; names[i]; i++) {
+ if (strcmp (name, names[i]) == 0)
+ return values[i];
+ }
+
+ return NULL;
+}
+
+static void
+start_element (GMarkupParseContext *context,
+ const char *element_name,
+ const char **attribute_names,
+ const char **attribute_values,
+ gpointer user_data,
+ GError **error)
+{
+ ParserData *data = user_data;
+
+ if (strcmp (element_name, "release") == 0) {
+ const char *value;
+ g_auto(GStrv) dmy = NULL;
+
+ data->ri = g_new0 (ReleaseInfo, 1);
+ data->ri->news = g_string_new ("");
- news = g_ptr_array_new_with_free_func (release_info_free);
+ value = find_attribute ("version", attribute_names, attribute_values);
+ data->ri->version = g_strdup (value);
- app = as_app_new ();
- if (!as_app_parse_file (app, file, 0, &error)) {
- g_warning ("Failed to parse %s: %s", file, error->message);
- return news;
+ value = find_attribute ("date", attribute_names, attribute_values);
+ dmy = g_strsplit (value, "-", 3);
+ if (g_strv_length (dmy) != 3) {
+ g_message ("Failed to parse release: %s", value);
+ data->ri->date = g_date_time_new_from_unix_utc (0);
+ }
+ else {
+ data->ri->date = g_date_time_new_utc (atoi (dmy[0]), atoi (dmy[1]), atoi (dmy[2]),
0, 0, 0);
+ }
+ }
+ else if (strcmp (element_name, "p") == 0 ||
+ strcmp (element_name, "li") == 0) {
+ if (data->ri) {
+ g_string_set_size (data->text, 0);
+ data->collect = TRUE;
+ }
}
+}
- releases = as_app_get_releases (app);
- for (i = 0; i < releases->len; i++) {
- AsRelease *rel = g_ptr_array_index (releases, i);
- ReleaseInfo *ri;
- const char *tmp;
+static void
+string_append_normalized (GString *s,
+ const char *str)
+{
+ gboolean initial = TRUE;
+ gboolean in_whitespace = FALSE;
+ const char *p;
- if (!version_between (as_release_get_version (rel), old_version, new_version))
+ for (p = str; *p; p = g_utf8_next_char (p)) {
+ gunichar ch = g_utf8_get_char (p);
+
+ if (g_unichar_isspace (ch)) {
+ in_whitespace = TRUE;
continue;
+ }
- ri = g_new0 (ReleaseInfo, 1);
- g_ptr_array_insert (news, -1, ri);
+ if (in_whitespace && !initial)
+ g_string_append_c (s, ' ');
- ri->version = g_strdup (as_release_get_version (rel));
+ g_string_append_unichar (s, ch);
+ in_whitespace = FALSE;
+ initial = FALSE;
+ }
+}
- if (as_release_get_timestamp (rel) > 0)
- ri->date = g_date_time_new_from_unix_utc ((gint64) as_release_get_timestamp (rel));
+static void
+end_element (GMarkupParseContext *context,
+ const char *element_name,
+ gpointer user_data,
+ GError **error)
+{
+ ParserData *data = user_data;
- tmp = as_release_get_description (rel, NULL);
- if (tmp != NULL)
- ri->news = as_markup_convert (tmp, AS_MARKUP_CONVERT_FORMAT_SIMPLE, NULL);
- else {
- g_warning ("Failed to convert markup in %s", file);
+ if (strcmp (element_name, "release") == 0) {
+ if (!version_between (data->ri->version, data->old_version, data->new_version))
+ release_info_free (data->ri);
+ else
+ g_ptr_array_add (data->result, data->ri);
+ data->ri = NULL;
+ }
+ else if (strcmp (element_name, "p") == 0) {
+ if (data->collect) {
+ data->collect = FALSE;
+ if (data->ri->news->len > 0)
+ g_string_append (data->ri->news, "\n");
+ string_append_normalized (data->ri->news, data->text->str);
+ }
+ }
+ else if (strcmp (element_name, "li") == 0) {
+ if (data->collect) {
+ data->collect = TRUE;
+ if (data->ri->news->len > 0)
+ g_string_append (data->ri->news, "\n");
+ g_string_append (data->ri->news, " ∙ ");
+ string_append_normalized (data->ri->news, data->text->str);
}
}
+}
+
+static void
+text (GMarkupParseContext *context,
+ const char *text,
+ gsize text_len,
+ gpointer user_data,
+ GError **error)
+{
+ ParserData *data = user_data;
+
+ if (data->collect)
+ g_string_append_len (data->text, text, text_len);
+}
+
+static GMarkupParser parser = {
+ start_element,
+ end_element,
+ text,
+ NULL,
+ NULL
+};
+
+static GPtrArray *
+parse_appdata (const char *file,
+ const char *new_version,
+ const char *old_version)
+{
+ g_autoptr(GMarkupParseContext) context = NULL;
+ g_autofree char *buffer = NULL;
+ gsize length;
+ g_autoptr(GError) error = NULL;
+ ParserData data;
+
+ data.result = g_ptr_array_new_with_free_func (release_info_free);
+ data.new_version = new_version;
+ data.old_version = old_version;
+ data.ri = NULL;
+ data.collect = FALSE;
+ data.text = g_string_new ("");
+
+ if (!g_file_get_contents (file, &buffer, &length, &error)) {
+ g_message ("Failed to read %s: %s", file, error->message);
+ goto out;
+ }
+
+ context = g_markup_parse_context_new (&parser, 0, &data, NULL);
+
+ if (!g_markup_parse_context_parse (context, buffer, length, &error)) {
+ g_message ("Failed to parse %s: %s", file, error->message);
+ g_ptr_array_set_size (data.result, 0);
+ }
+
+out:
+ g_string_free (data.text, TRUE);
+
+ return data.result;
+}
+
+GPtrArray *
+get_release_info (const char *new_version,
+ const char *old_version)
+{
+ g_autofree char *file = NULL;
+
+ file = g_build_filename (DATADIR, "appdata", "org.gnome.Recipes.appdata.xml", NULL);
- return news;
+ return parse_appdata (file, new_version, old_version);
}
diff --git a/src/gr-appdata.h b/src/gr-appdata.h
index c05f04a..d0ead8e 100644
--- a/src/gr-appdata.h
+++ b/src/gr-appdata.h
@@ -27,7 +27,7 @@ G_BEGIN_DECLS
typedef struct {
char *version;
GDateTime *date;
- char *news;
+ GString *news;
} ReleaseInfo;
GPtrArray *get_release_info (const char *new_version,
diff --git a/src/gr-window.c b/src/gr-window.c
index 41c2626..d7d3030 100644
--- a/src/gr-window.c
+++ b/src/gr-window.c
@@ -1202,7 +1202,7 @@ gr_window_show_news (GrWindow *window)
}
if (ri->news) {
- label = gtk_label_new (ri->news);
+ label = gtk_label_new (ri->news->str);
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
gtk_label_set_max_width_chars (GTK_LABEL (label), 55);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]