[gnome-software] plugins: Add a local ratings plugin for testing the ratings widget and search ordering



commit be526c5f1263551b6e6fea0dd8dd5d750f1c21a6
Author: Richard Hughes <richard hughsie com>
Date:   Mon Mar 18 17:28:52 2013 +0000

    plugins: Add a local ratings plugin for testing the ratings widget and search ordering

 configure.ac                          |    1 +
 src/gs-main.c                         |    1 +
 src/plugins/Makefile.am               |    9 ++-
 src/plugins/README                    |    6 +
 src/plugins/gs-plugin-local-ratings.c |  202 +++++++++++++++++++++++++++++++++
 5 files changed, 218 insertions(+), 1 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 8f77462..7ca2959 100644
--- a/configure.ac
+++ b/configure.ac
@@ -74,6 +74,7 @@ dnl ---------------------------------------------------------------------------
 PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.31.10 gobject-2.0 gthread-2.0 gio-2.0 >= 2.25.9 gmodule-2.0)
 PKG_CHECK_MODULES(GTK, gtk+-3.0 >= 3.5.6)
 PKG_CHECK_MODULES(PACKAGEKIT, packagekit-glib2 >= 0.8.6)
+PKG_CHECK_MODULES(SQLITE, sqlite3)
 
 dnl ---------------------------------------------------------------------------
 dnl - Makefiles, etc.
diff --git a/src/gs-main.c b/src/gs-main.c
index dd4b349..797d69a 100644
--- a/src/gs-main.c
+++ b/src/gs-main.c
@@ -1121,6 +1121,7 @@ main (int argc, char **argv)
        gs_plugin_loader_set_enabled (priv->plugin_loader, "hardcoded-kind", TRUE);
        gs_plugin_loader_set_enabled (priv->plugin_loader, "hardcoded-popular", TRUE);
        gs_plugin_loader_set_enabled (priv->plugin_loader, "hardcoded-ratings", TRUE);
+       gs_plugin_loader_set_enabled (priv->plugin_loader, "local-ratings", TRUE);
        gs_plugin_loader_set_enabled (priv->plugin_loader, "packagekit", TRUE);
        gs_plugin_loader_set_enabled (priv->plugin_loader, "desktopdb", TRUE);
        gs_plugin_loader_set_enabled (priv->plugin_loader, "datadir-apps", TRUE);
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index 79f3723..59f7d37 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -6,6 +6,7 @@ AM_CPPFLAGS =                                           \
        $(GTK_CFLAGS)                                   \
        $(SQLITE_CFLAGS)                                \
        $(PACKAGEKIT_CFLAGS)                            \
+       $(SQLITE_CFLAGS)                                \
        -DBINDIR=\"$(bindir)\"                          \
        -DDATADIR=\"$(datadir)\"                        \
        -DG_LOG_DOMAIN=\"GsPlugin\"                     \
@@ -25,6 +26,7 @@ plugin_LTLIBRARIES =                                  \
        libgs_plugin_hardcoded-kind.la                  \
        libgs_plugin_hardcoded-popular.la               \
        libgs_plugin_hardcoded-ratings.la               \
+       libgs_plugin_local-ratings.la                   \
        libgs_plugin_packagekit.la
 
 libgs_plugin_dummy_la_SOURCES = gs-plugin-dummy.c
@@ -43,10 +45,15 @@ libgs_plugin_hardcoded_popular_la_LDFLAGS = -module -avoid-version
 libgs_plugin_hardcoded_popular_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARNINGFLAGS_C)
 
 libgs_plugin_hardcoded_ratings_la_SOURCES = gs-plugin-hardcoded-ratings.c
-libgs_plugin_hardcoded_ratings_la_LIBADD = $(GS_PLUGIN_LIBS)
+libgs_plugin_hardcoded_ratings_la_LIBADD = $(GS_PLUGIN_LIBS) $(SQLITE_LIBS)
 libgs_plugin_hardcoded_ratings_la_LDFLAGS = -module -avoid-version
 libgs_plugin_hardcoded_ratings_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARNINGFLAGS_C)
 
+libgs_plugin_local_ratings_la_SOURCES = gs-plugin-local-ratings.c
+libgs_plugin_local_ratings_la_LIBADD = $(GS_PLUGIN_LIBS) $(SQLITE_LIBS)
+libgs_plugin_local_ratings_la_LDFLAGS = -module -avoid-version
+libgs_plugin_local_ratings_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARNINGFLAGS_C)
+
 libgs_plugin_packagekit_la_SOURCES = gs-plugin-packagekit.c
 libgs_plugin_packagekit_la_LIBADD = $(GS_PLUGIN_LIBS) $(PACKAGEKIT_LIBS)
 libgs_plugin_packagekit_la_LDFLAGS = -module -avoid-version
diff --git a/src/plugins/README b/src/plugins/README
index 9342a76..a7a6b27 100644
--- a/src/plugins/README
+++ b/src/plugins/README
@@ -75,6 +75,12 @@ Methods:     <nothing>
 Requires:      <nothing>
 Refines:       [id]->[rating]
 
+== local-ratings ==
+Overview:      Provides a local SQL database of user-set ratings, mainly useful for testing.
+Methods:       <nothing>
+Requires:      <nothing>
+Refines:       [id]->[rating]
+
 == packagekit ==
 Overview:      Uses the system PackageKit instance to return package data.
 Methods:       Search
diff --git a/src/plugins/gs-plugin-local-ratings.c b/src/plugins/gs-plugin-local-ratings.c
new file mode 100644
index 0000000..6094357
--- /dev/null
+++ b/src/plugins/gs-plugin-local-ratings.c
@@ -0,0 +1,202 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2013 Richard Hughes <richard hughsie com>
+ *
+ * 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 <errno.h>
+#include <sqlite3.h>
+#include <stdlib.h>
+
+#include <gs-plugin.h>
+
+struct GsPluginPrivate {
+       gboolean                 loaded;
+       gchar                   *db_path;
+       sqlite3                 *db;
+};
+
+/**
+ * gs_plugin_get_name:
+ */
+const gchar *
+gs_plugin_get_name (void)
+{
+       return "local-ratings";
+}
+
+/**
+ * gs_plugin_local_ratings_ensure_file_directory:
+ **/
+static void
+gs_plugin_local_ratings_ensure_file_directory (const gchar *path)
+{
+       gchar *parent;
+
+       parent = g_path_get_dirname (path);
+       if (g_mkdir_with_parents (parent, 0755) == -1)
+               g_warning ("%s", g_strerror (errno));
+
+       g_free (parent);
+}
+
+/**
+ * gs_plugin_initialize:
+ */
+void
+gs_plugin_initialize (GsPlugin *plugin)
+{
+       /* create private area */
+       plugin->priv = GS_PLUGIN_GET_PRIVATE (GsPluginPrivate);
+       plugin->priv->db_path = g_build_filename (g_get_home_dir (),
+                                                 ".local",
+                                                 "share",
+                                                 "gnome-software",
+                                                 "hardcoded-ratings.db",
+                                                 NULL);
+}
+
+/**
+ * gs_plugin_get_priority:
+ */
+gdouble
+gs_plugin_get_priority (GsPlugin *plugin)
+{
+       return -99.0f;
+}
+
+/**
+ * gs_plugin_destroy:
+ */
+void
+gs_plugin_destroy (GsPlugin *plugin)
+{
+       g_free (plugin->priv->db_path);
+       sqlite3_close (plugin->priv->db);
+}
+
+/**
+ * gs_plugin_local_ratings_load_db:
+ */
+static gboolean
+gs_plugin_local_ratings_load_db (GsPlugin *plugin,
+                                GError **error)
+{
+       const gchar *statement;
+       gboolean ret = TRUE;
+       gchar *error_msg = NULL;
+       gint rc;
+
+       g_debug ("trying to open database '%s'", plugin->priv->db_path);
+       gs_plugin_local_ratings_ensure_file_directory (plugin->priv->db_path);
+       rc = sqlite3_open (plugin->priv->db_path, &plugin->priv->db);
+       if (rc != SQLITE_OK) {
+               ret = FALSE;
+               g_set_error (error,
+                            GS_PLUGIN_ERROR,
+                            GS_PLUGIN_ERROR_FAILED,
+                            "Can't open transaction database: %s",
+                            sqlite3_errmsg (plugin->priv->db));
+               goto out;
+       }
+
+       /* we don't need to keep doing fsync */
+       sqlite3_exec (plugin->priv->db, "PRAGMA synchronous=OFF", NULL, NULL, NULL);
+
+       /* create table if required */
+       rc = sqlite3_exec (plugin->priv->db, "SELECT * FROM ratings LIMIT 1", NULL, NULL, &error_msg);
+       if (rc != SQLITE_OK) {
+               g_debug ("creating table to repair: %s", error_msg);
+               sqlite3_free (error_msg);
+               statement = "CREATE TABLE ratings ("
+                           "app_id TEXT PRIMARY KEY,"
+                           "rating INTEGER DEFAULT 0);";
+               sqlite3_exec (plugin->priv->db, statement, NULL, NULL, NULL);
+       }
+
+       /* success */
+       plugin->priv->loaded = TRUE;
+out:
+       return ret;
+}
+
+/**
+ * gs_plugin_local_ratings_sqlite_cb:
+ **/
+static gint
+gs_plugin_local_ratings_sqlite_cb (void *data, gint argc, gchar **argv, gchar **col_name)
+{
+       gint *rating = (gint *) data;
+       *rating = atoi (argv[0]);
+       return 0;
+}
+
+/**
+ * gs_plugin_local_find_app:
+ */
+static gint
+gs_plugin_local_find_app (GsPlugin *plugin, const gchar *app_id)
+{
+       gchar *statement;
+       gint rating = -1;
+
+       statement = g_strdup_printf ("SELECT rating FROM ratings WHERE app_id = '%s'", app_id);
+       sqlite3_exec (plugin->priv->db,
+                     statement,
+                     gs_plugin_local_ratings_sqlite_cb,
+                     &rating,
+                     NULL);
+       g_free (statement);
+       return rating;
+}
+
+/**
+ * gs_plugin_refine:
+ */
+gboolean
+gs_plugin_refine (GsPlugin *plugin,
+                 GList *list,
+                 GCancellable *cancellable,
+                 GError **error)
+{
+       gboolean ret = TRUE;
+       gint rating;
+       GList *l;
+       GsApp *app;
+
+       /* already loaded */
+       if (!plugin->priv->loaded) {
+               ret = gs_plugin_local_ratings_load_db (plugin, error);
+               if (!ret)
+                       goto out;
+       }
+
+       /* add any missing ratings data */
+       for (l = list; l != NULL; l = l->next) {
+               app = GS_APP (l->data);
+               if (gs_app_get_rating (app) != -1)
+                       continue;
+               rating = gs_plugin_local_find_app (plugin, gs_app_get_id (app));
+               if (rating != -1)
+                       gs_app_set_rating (app, rating);
+       }
+out:
+       return ret;
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]