[gnome-control-center] printers: get printer job attributes async
- From: Felipe Borges <felipeborges src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center] printers: get printer job attributes async
- Date: Thu, 3 Mar 2016 15:06:39 +0000 (UTC)
commit dc7b78ca423b710bda1109c278e863235a86f2e7
Author: Felipe Borges <felipeborges gnome org>
Date: Wed Feb 17 15:25:14 2016 +0100
printers: get printer job attributes async
https://bugzilla.gnome.org/show_bug.cgi?id=748336
panels/printers/cc-printers-panel.c | 107 +++++++++++++++-----------
panels/printers/pp-job.c | 144 +++++++++++++++++++++++++++++++++++
panels/printers/pp-job.h | 18 ++++-
3 files changed, 219 insertions(+), 50 deletions(-)
---
diff --git a/panels/printers/cc-printers-panel.c b/panels/printers/cc-printers-panel.c
index e4ec22b..1159495 100644
--- a/panels/printers/cc-printers-panel.c
+++ b/panels/printers/cc-printers-panel.c
@@ -39,6 +39,7 @@
#include "pp-utils.h"
#include "pp-maintenance-command.h"
#include "pp-cups.h"
+#include "pp-job.h"
CC_PANEL_REGISTER (CcPrintersPanel, cc_printers_panel)
@@ -271,6 +272,56 @@ cc_printers_panel_class_init (CcPrintersPanelClass *klass)
}
static void
+on_get_job_attributes_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ CcPrintersPanel *self = (CcPrintersPanel*) user_data;
+ CcPrintersPanelPrivate *priv;
+ const gchar *job_originating_user_name;
+ const gchar *job_printer_uri;
+ GVariant *attributes;
+ GVariant *username;
+ GVariant *printer_uri;
+ GError *error = NULL;
+
+ priv = PRINTERS_PANEL_PRIVATE (self);
+
+ attributes = pp_job_get_attributes_finish (PP_JOB (source_object), res, &error);
+ g_object_unref (source_object);
+
+ if (attributes != NULL)
+ {
+ if ((username = g_variant_lookup_value (attributes, "job-originating-user-name", G_VARIANT_TYPE
("as"))) != NULL)
+ {
+ if ((printer_uri = g_variant_lookup_value (attributes, "job-printer-uri", G_VARIANT_TYPE ("as")))
!= NULL)
+ {
+ job_originating_user_name = g_variant_get_string (g_variant_get_child_value (username, 0),
NULL);
+ job_printer_uri = g_variant_get_string (g_variant_get_child_value (printer_uri, 0), NULL);
+
+ if (job_originating_user_name != NULL && job_printer_uri != NULL &&
+ g_strcmp0 (job_originating_user_name, cupsUser ()) == 0 &&
+ g_strrstr (job_printer_uri, "/") != 0 &&
+ priv->current_dest >= 0 &&
+ priv->current_dest < priv->num_dests &&
+ priv->dests != NULL &&
+ g_strcmp0 (g_strrstr (job_printer_uri, "/") + 1,
+ priv->dests[priv->current_dest].name) == 0)
+ {
+ update_jobs_count (self);
+ }
+
+ g_variant_unref (printer_uri);
+ }
+
+ g_variant_unref (username);
+ }
+
+ g_variant_unref (attributes);
+ }
+}
+
+static void
on_cups_notification (GDBusConnection *connection,
const char *sender_name,
const char *object_path,
@@ -280,23 +331,22 @@ on_cups_notification (GDBusConnection *connection,
gpointer user_data)
{
CcPrintersPanel *self = (CcPrintersPanel*) user_data;
- CcPrintersPanelPrivate *priv;
gboolean printer_is_accepting_jobs;
gchar *printer_name = NULL;
gchar *text = NULL;
gchar *printer_uri = NULL;
gchar *printer_state_reasons = NULL;
+ PpJob *job;
gchar *job_state_reasons = NULL;
gchar *job_name = NULL;
guint job_id;
gint printer_state;
gint job_state;
gint job_impressions_completed;
- static const char * const requested_attrs[] = {
+ static gchar *requested_attrs[] = {
"job-printer-uri",
- "job-originating-user-name"};
-
- priv = PRINTERS_PANEL_PRIVATE (self);
+ "job-originating-user-name",
+ NULL };
if (g_strcmp0 (signal_name, "PrinterAdded") != 0 &&
g_strcmp0 (signal_name, "PrinterDeleted") != 0 &&
@@ -342,47 +392,12 @@ on_cups_notification (GDBusConnection *connection,
else if (g_strcmp0 (signal_name, "JobCreated") == 0 ||
g_strcmp0 (signal_name, "JobCompleted") == 0)
{
- http_t *http;
- gchar *job_uri;
- ipp_t *request, *response;
-
- job_uri = g_strdup_printf ("ipp://localhost/jobs/%d", job_id);
- if ((http = httpConnectEncrypt (cupsServer (), ippPort (),
- cupsEncryption ())) != NULL)
- {
- request = ippNewRequest (IPP_GET_JOB_ATTRIBUTES);
- ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI,
- "job-uri", NULL, job_uri);
- ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_NAME,
- "requesting-user-name", NULL, cupsUser ());
- ippAddStrings (request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
- "requested-attributes", G_N_ELEMENTS (requested_attrs), NULL, requested_attrs);
- response = cupsDoRequest (http, request, "/");
-
- if (response)
- {
- if (ippGetStatusCode (response) <= IPP_OK_CONFLICT)
- {
- ipp_attribute_t *attr_username = NULL;
- ipp_attribute_t *attr_printer_uri = NULL;
-
- attr_username = ippFindAttribute(response, "job-originating-user-name", IPP_TAG_NAME);
- attr_printer_uri = ippFindAttribute(response, "job-printer-uri", IPP_TAG_URI);
- if (attr_username && attr_printer_uri &&
- g_strcmp0 (ippGetString (attr_username, 0, NULL), cupsUser ()) == 0 &&
- g_strrstr (ippGetString (attr_printer_uri, 0, NULL), "/") != 0 &&
- priv->current_dest >= 0 &&
- priv->current_dest < priv->num_dests &&
- priv->dests != NULL &&
- g_strcmp0 (g_strrstr (ippGetString (attr_printer_uri, 0, NULL), "/") + 1,
- priv->dests[priv->current_dest].name) == 0)
- update_jobs_count (self);
- }
- ippDelete(response);
- }
- httpClose (http);
- }
- g_free (job_uri);
+ job = g_object_new (PP_TYPE_JOB, "id", job_id, NULL);
+ pp_job_get_attributes_async (job,
+ requested_attrs,
+ NULL,
+ on_get_job_attributes_cb,
+ self);
}
}
diff --git a/panels/printers/pp-job.c b/panels/printers/pp-job.c
index 42200a7..0c7c267 100644
--- a/panels/printers/pp-job.c
+++ b/panels/printers/pp-job.c
@@ -20,6 +20,9 @@
#include "pp-job.h"
+#include <gio/gio.h>
+#include <cups/cups.h>
+
typedef struct
{
GObject parent;
@@ -249,3 +252,144 @@ pp_job_class_init (PpJobClass *class)
g_object_class_install_properties (object_class, LAST_PROPERTY, properties);
}
+
+static void
+_pp_job_get_attributes_thread (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cancellable)
+{
+ ipp_attribute_t *attr = NULL;
+ GVariantBuilder builder;
+ GVariant *attributes = NULL;
+ gchar **attributes_names = task_data;
+ PpJobPrivate *priv;
+ ipp_t *request;
+ ipp_t *response = NULL;
+ gchar *job_uri;
+ gint i, j, length = 0, n_attrs = 0;
+
+ priv = pp_job_get_instance_private (source_object);
+
+ job_uri = g_strdup_printf ("ipp://localhost/jobs/%d", priv->id);
+
+ if (attributes_names != NULL)
+ {
+ length = g_strv_length (attributes_names);
+
+ request = ippNewRequest (IPP_GET_JOB_ATTRIBUTES);
+ ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "job-uri", NULL, job_uri);
+ ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+ "requesting-user-name", NULL, cupsUser ());
+ ippAddStrings (request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes", length, NULL, (const char **) attributes_names);
+ response = cupsDoRequest (CUPS_HTTP_DEFAULT, request, "/");
+ }
+
+ if (response != NULL)
+ {
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
+
+ for (j = 0; j < length; j++)
+ {
+ attr = ippFindAttribute (response, attributes_names[j], IPP_TAG_ZERO);
+ n_attrs = ippGetCount (attr);
+ if (attr != NULL && n_attrs > 0 && ippGetValueTag (attr) != IPP_TAG_NOVALUE)
+ {
+ const GVariantType *type = NULL;
+ GVariant **values;
+ GVariant *range[2];
+ gint range_uppervalue;
+
+ values = g_new (GVariant*, n_attrs);
+
+ switch (ippGetValueTag (attr))
+ {
+ case IPP_TAG_INTEGER:
+ case IPP_TAG_ENUM:
+ type = G_VARIANT_TYPE_INT32;
+
+ for (i = 0; i < n_attrs; i++)
+ values[i] = g_variant_new_int32 (ippGetInteger (attr, i));
+ break;
+
+ case IPP_TAG_NAME:
+ case IPP_TAG_STRING:
+ case IPP_TAG_TEXT:
+ case IPP_TAG_URI:
+ case IPP_TAG_KEYWORD:
+ case IPP_TAG_URISCHEME:
+ type = G_VARIANT_TYPE_STRING;
+
+ for (i = 0; i < n_attrs; i++)
+ values[i] = g_variant_new_string (ippGetString (attr, i, NULL));
+ break;
+
+ case IPP_TAG_RANGE:
+ type = G_VARIANT_TYPE_TUPLE;
+
+ for (i = 0; i < n_attrs; i++)
+ {
+ range[0] = g_variant_new_int32 (ippGetRange (attr, i, &(range_uppervalue)));
+ range[1] = g_variant_new_int32 (range_uppervalue);
+
+ values[i] = g_variant_new_tuple (range, 2);
+ }
+ break;
+
+ case IPP_TAG_BOOLEAN:
+ type = G_VARIANT_TYPE_BOOLEAN;
+
+ for (i = 0; i < n_attrs; i++)
+ values[i] = g_variant_new_boolean (ippGetBoolean (attr, i));
+ break;
+
+ default:
+ /* do nothing (switch w/ enumeration type) */
+ break;
+ }
+
+ if (type != NULL)
+ {
+ g_variant_builder_add (&builder, "{sv}",
+ attributes_names[j],
+ g_variant_new_array (type, values, n_attrs));
+ }
+
+ g_free (values);
+ }
+ }
+
+ attributes = g_variant_builder_end (&builder);
+ }
+ g_free (job_uri);
+
+ g_task_return_pointer (task, attributes, (GDestroyNotify) g_variant_unref);
+}
+
+void
+pp_job_get_attributes_async (PpJob *job,
+ gchar **attributes_names,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task;
+
+ task = g_task_new (job, cancellable, callback, user_data);
+ g_task_set_task_data (task, g_strdupv (attributes_names), (GDestroyNotify) g_strfreev);
+ g_task_run_in_thread (task, _pp_job_get_attributes_thread);
+
+ g_object_unref (task);
+}
+
+GVariant *
+pp_job_get_attributes_finish (PpJob *job,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (g_task_is_valid (result, job), NULL);
+
+ return g_task_propagate_pointer (G_TASK (result), error);
+}
diff --git a/panels/printers/pp-job.h b/panels/printers/pp-job.h
index 35e16e9..ba6f461 100644
--- a/panels/printers/pp-job.h
+++ b/panels/printers/pp-job.h
@@ -36,11 +36,21 @@ struct _PpJob
GObject parent_instance;
};
-void pp_job_set_hold_until_async (PpJob *job,
- const gchar *job_hold_until);
+void pp_job_set_hold_until_async (PpJob *job,
+ const gchar *job_hold_until);
-void pp_job_cancel_purge_async (PpJob *job,
- gboolean job_purge);
+void pp_job_cancel_purge_async (PpJob *job,
+ gboolean job_purge);
+
+void pp_job_get_attributes_async (PpJob *job,
+ gchar **attributes_names,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+GVariant *pp_job_get_attributes_finish (PpJob *job,
+ GAsyncResult *result,
+ GError **error);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]