|
Packit |
87b8d1 |
/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8; tab-width: 8 -*- */
|
|
Packit |
87b8d1 |
/*
|
|
Packit |
87b8d1 |
* libgfbgraph - GObject library for Facebook Graph API
|
|
Packit |
87b8d1 |
* Copyright (C) 2013 Álvaro Peña <alvaropg@gmail.com>
|
|
Packit |
87b8d1 |
*
|
|
Packit |
87b8d1 |
* GFBGraph is free software; you can redistribute it and/or
|
|
Packit |
87b8d1 |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit |
87b8d1 |
* License as published by the Free Software Foundation; either
|
|
Packit |
87b8d1 |
* version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
87b8d1 |
*
|
|
Packit |
87b8d1 |
* GFBGraph is distributed in the hope that it will be useful,
|
|
Packit |
87b8d1 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
87b8d1 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
87b8d1 |
* Lesser General Public License for more details.
|
|
Packit |
87b8d1 |
*
|
|
Packit |
87b8d1 |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
87b8d1 |
* License along with GFBGraph. If not, see <http://www.gnu.org/licenses/>.
|
|
Packit |
87b8d1 |
*/
|
|
Packit |
87b8d1 |
|
|
Packit |
87b8d1 |
/**
|
|
Packit |
87b8d1 |
* SECTION:gfbgraph-connectable
|
|
Packit |
87b8d1 |
* @title: GFBGraphConnectable
|
|
Packit |
87b8d1 |
* @short_description: Connectable interface for nodes
|
|
Packit |
87b8d1 |
* @include: gfbgraph/gfbgraph.h
|
|
Packit |
87b8d1 |
*
|
|
Packit |
87b8d1 |
* #GFBGraphConnectable interface allow the connection between nodes.
|
|
Packit |
87b8d1 |
* You can see the posible (not necesary implemented) connections in
|
|
Packit |
87b8d1 |
* the section "Connections" in any node object in the
|
|
Packit |
87b8d1 |
* <ulink url="https://developers.facebook.com/docs/reference/api/">Facebook Graph API documentation</ulink>
|
|
Packit |
87b8d1 |
**/
|
|
Packit |
87b8d1 |
|
|
Packit |
87b8d1 |
#include "gfbgraph-connectable.h"
|
|
Packit |
87b8d1 |
#include "gfbgraph-node.h"
|
|
Packit |
87b8d1 |
|
|
Packit |
87b8d1 |
#include <json-glib/json-glib.h>
|
|
Packit |
87b8d1 |
|
|
Packit |
87b8d1 |
G_DEFINE_INTERFACE (GFBGraphConnectable, gfbgraph_connectable, GFBGRAPH_TYPE_NODE)
|
|
Packit |
87b8d1 |
|
|
Packit |
87b8d1 |
static void
|
|
Packit |
87b8d1 |
gfbgraph_connectable_default_init (GFBGraphConnectableInterface *iface)
|
|
Packit |
87b8d1 |
{
|
|
Packit |
87b8d1 |
iface->connections = NULL;
|
|
Packit |
87b8d1 |
|
|
Packit |
87b8d1 |
iface->get_connection_post_params = NULL;
|
|
Packit |
87b8d1 |
iface->parse_connected_data = NULL;
|
|
Packit |
87b8d1 |
}
|
|
Packit |
87b8d1 |
|
|
Packit |
87b8d1 |
static GHashTable*
|
|
Packit |
87b8d1 |
get_connections (GFBGraphConnectableInterface *iface)
|
|
Packit |
87b8d1 |
{
|
|
Packit |
87b8d1 |
/* The GHashTable contains the connections for a node.
|
|
Packit |
87b8d1 |
* The key must be the g_type_name() of a GFBGRAPH_TYPE_NODE, and the value
|
|
Packit |
87b8d1 |
* must be the function name to call in order to retrieve the nodes connected
|
|
Packit |
87b8d1 |
* to the GFBGraphNode indicated by GFBGRAPH_TYPE_NODE.
|
|
Packit |
87b8d1 |
*/
|
|
Packit |
87b8d1 |
GHashTable *connections;
|
|
Packit |
87b8d1 |
|
|
Packit |
87b8d1 |
connections = iface->connections;
|
|
Packit |
87b8d1 |
/* If no connections... Why you implement this iface? */
|
|
Packit |
87b8d1 |
g_assert (g_hash_table_size (connections) > 0);
|
|
Packit |
87b8d1 |
|
|
Packit |
87b8d1 |
return connections;
|
|
Packit |
87b8d1 |
}
|
|
Packit |
87b8d1 |
|
|
Packit |
87b8d1 |
/**
|
|
Packit |
87b8d1 |
* gfbgraph_connectable_get_connection_post_params:
|
|
Packit |
87b8d1 |
* @self: a #GFBGraphConnectable.
|
|
Packit |
87b8d1 |
* @node_type: a #GType, required a #GFBGRAPH_TYPE_NODE or children.
|
|
Packit |
87b8d1 |
*
|
|
Packit |
87b8d1 |
* Get the params to be inserted in a request to the Facebook Graph API
|
|
Packit |
87b8d1 |
* in order to append the node @self to a node of type @node_type.
|
|
Packit |
87b8d1 |
*
|
|
Packit |
87b8d1 |
* Returns: (transfer full): A string based #GHashTable with the params and his values or %NULL.
|
|
Packit |
87b8d1 |
**/
|
|
Packit |
87b8d1 |
GHashTable*
|
|
Packit |
87b8d1 |
gfbgraph_connectable_get_connection_post_params (GFBGraphConnectable *self, GType node_type)
|
|
Packit |
87b8d1 |
{
|
|
Packit |
87b8d1 |
GFBGraphConnectableInterface *iface;
|
|
Packit |
87b8d1 |
|
|
Packit |
87b8d1 |
g_return_val_if_fail (GFBGRAPH_IS_CONNECTABLE (self), NULL);
|
|
Packit |
87b8d1 |
g_return_val_if_fail (g_type_is_a (node_type, GFBGRAPH_TYPE_NODE), NULL);
|
|
Packit |
87b8d1 |
g_return_val_if_fail (gfbgraph_connectable_is_connectable_to (self, node_type), NULL);
|
|
Packit |
87b8d1 |
|
|
Packit |
87b8d1 |
iface = GFBGRAPH_CONNECTABLE_GET_IFACE (self);
|
|
Packit |
87b8d1 |
g_assert (iface->get_connection_post_params != NULL);
|
|
Packit |
87b8d1 |
|
|
Packit |
87b8d1 |
return iface->get_connection_post_params (self, node_type);
|
|
Packit |
87b8d1 |
}
|
|
Packit |
87b8d1 |
|
|
Packit |
87b8d1 |
/**
|
|
Packit |
87b8d1 |
* gfbgraph_connectable_parse_connected_data:
|
|
Packit |
87b8d1 |
* @self: a #GFBGraphConnectable.
|
|
Packit |
87b8d1 |
* @payload: a const #gchar with the response string from the Facebook Graph API.
|
|
Packit |
87b8d1 |
* @error: (allow-none): a #GError.
|
|
Packit |
87b8d1 |
*
|
|
Packit |
87b8d1 |
* Parse the response contained in @payload when a gfbgraph_node_get_connection_nodes() was
|
|
Packit |
87b8d1 |
* executed.
|
|
Packit |
87b8d1 |
*
|
|
Packit |
87b8d1 |
* Returns: (element-type GFBGraphNode) (transfer full): a newly-allocated #GList of #GFBGraphNode created from the @payload or %NULL.
|
|
Packit |
87b8d1 |
**/
|
|
Packit |
87b8d1 |
GList*
|
|
Packit |
87b8d1 |
gfbgraph_connectable_parse_connected_data (GFBGraphConnectable *self, const gchar *payload, GError **error)
|
|
Packit |
87b8d1 |
{
|
|
Packit |
87b8d1 |
GFBGraphConnectableInterface *iface;
|
|
Packit |
87b8d1 |
|
|
Packit |
87b8d1 |
g_return_val_if_fail (GFBGRAPH_IS_CONNECTABLE (self), NULL);
|
|
Packit |
87b8d1 |
|
|
Packit |
87b8d1 |
iface = GFBGRAPH_CONNECTABLE_GET_IFACE (self);
|
|
Packit |
87b8d1 |
g_assert (iface->parse_connected_data != NULL);
|
|
Packit |
87b8d1 |
|
|
Packit |
87b8d1 |
return iface->parse_connected_data (self, payload, error);
|
|
Packit |
87b8d1 |
}
|
|
Packit |
87b8d1 |
|
|
Packit |
87b8d1 |
|
|
Packit |
87b8d1 |
/**
|
|
Packit |
87b8d1 |
* gfbgraph_connectable_is_connectable_to:
|
|
Packit |
87b8d1 |
* @self: a #GFBGraphConnectable.
|
|
Packit |
87b8d1 |
* @node_type: a #GType, required a #GFBGRAPH_TYPE_NODE or children.
|
|
Packit |
87b8d1 |
*
|
|
Packit |
87b8d1 |
* Check if @self object, normally a #GFBGraphNode implementing the #GFBGraphConnectable interface,
|
|
Packit |
87b8d1 |
* has the possibility to be connected to another node of type @node_type.
|
|
Packit |
87b8d1 |
*
|
|
Packit |
87b8d1 |
* Returns: %TRUE in case that the @self object can be connected to a node of type @node_type,
|
|
Packit |
87b8d1 |
* %FALSE otherwise.
|
|
Packit |
87b8d1 |
**/
|
|
Packit |
87b8d1 |
gboolean
|
|
Packit |
87b8d1 |
gfbgraph_connectable_is_connectable_to (GFBGraphConnectable *self, GType node_type)
|
|
Packit |
87b8d1 |
{
|
|
Packit |
87b8d1 |
GFBGraphConnectableInterface *iface;
|
|
Packit |
87b8d1 |
GHashTable *connections;
|
|
Packit |
87b8d1 |
|
|
Packit |
87b8d1 |
g_return_val_if_fail (GFBGRAPH_IS_CONNECTABLE (self), FALSE);
|
|
Packit |
87b8d1 |
g_return_val_if_fail (g_type_is_a (node_type, GFBGRAPH_TYPE_NODE), FALSE);
|
|
Packit |
87b8d1 |
|
|
Packit |
87b8d1 |
iface = GFBGRAPH_CONNECTABLE_GET_IFACE (self);
|
|
Packit |
87b8d1 |
|
|
Packit |
87b8d1 |
connections = get_connections (iface);
|
|
Packit |
87b8d1 |
return g_hash_table_contains (connections, g_type_name (node_type));
|
|
Packit |
87b8d1 |
}
|
|
Packit |
87b8d1 |
|
|
Packit |
87b8d1 |
/**
|
|
Packit |
87b8d1 |
* gfbgraph_connectable_get_connection_path:
|
|
Packit |
87b8d1 |
* @self: a #GFBGraphConnectable.
|
|
Packit |
87b8d1 |
* @node_type: a #GType, required a #GFBGRAPH_TYPE_NODE or children.
|
|
Packit |
87b8d1 |
*
|
|
Packit |
87b8d1 |
* Get the Facebook Graph API function path to retrieve the nodes connected with @node_type
|
|
Packit |
87b8d1 |
* managed by the #GFBGraphConnectable object.
|
|
Packit |
87b8d1 |
*
|
|
Packit |
87b8d1 |
* Returns: (transfer none): a const #gchar with the function path or %NULL.
|
|
Packit |
87b8d1 |
**/
|
|
Packit |
87b8d1 |
const gchar*
|
|
Packit |
87b8d1 |
gfbgraph_connectable_get_connection_path (GFBGraphConnectable *self, GType node_type)
|
|
Packit |
87b8d1 |
{
|
|
Packit |
87b8d1 |
GFBGraphConnectableInterface *iface;
|
|
Packit |
87b8d1 |
GHashTable *connections;
|
|
Packit |
87b8d1 |
|
|
Packit |
87b8d1 |
g_return_val_if_fail (GFBGRAPH_IS_CONNECTABLE (self), NULL);
|
|
Packit |
87b8d1 |
g_return_val_if_fail (g_type_is_a (node_type, GFBGRAPH_TYPE_NODE), NULL);
|
|
Packit |
87b8d1 |
g_return_val_if_fail (gfbgraph_connectable_is_connectable_to (self, node_type), NULL);
|
|
Packit |
87b8d1 |
|
|
Packit |
87b8d1 |
iface = GFBGRAPH_CONNECTABLE_GET_IFACE (self);
|
|
Packit |
87b8d1 |
|
|
Packit |
87b8d1 |
connections = get_connections (iface);
|
|
Packit |
87b8d1 |
return (const gchar *) g_hash_table_lookup (connections, g_type_name (node_type));
|
|
Packit |
87b8d1 |
}
|
|
Packit |
87b8d1 |
|
|
Packit |
87b8d1 |
/**
|
|
Packit |
87b8d1 |
* gfbgraph_connectable_default_parse_connected_data:
|
|
Packit |
87b8d1 |
* @self: a #GFBGraphConnectable.
|
|
Packit |
87b8d1 |
* @payload: a const #gchar with the response string from the Facebook Graph API.
|
|
Packit |
87b8d1 |
* @error: (allow-none): a #GError or %NULL.
|
|
Packit |
87b8d1 |
*
|
|
Packit |
87b8d1 |
* In most cases, #GFBGraphConnectable implementers can use this function in order to parse
|
|
Packit |
87b8d1 |
* the response when a gfbgraph_node_get_connection_nodes() is executed and the
|
|
Packit |
87b8d1 |
* gfbgraph_connectable_parse_connected_data() was called.
|
|
Packit |
87b8d1 |
*
|
|
Packit |
87b8d1 |
* Normally, Facebook Graph API returns the connections in the same way, using JSON objects,
|
|
Packit |
87b8d1 |
* with a root object called "data".
|
|
Packit |
87b8d1 |
*
|
|
Packit |
87b8d1 |
* Returns: (element-type GFBGraphNode) (transfer full): a newly-allocated #GList of #GFBGraphNode with the same #GType as @self.
|
|
Packit |
87b8d1 |
**/
|
|
Packit |
87b8d1 |
GList*
|
|
Packit |
87b8d1 |
gfbgraph_connectable_default_parse_connected_data (GFBGraphConnectable *self, const gchar *payload, GError **error)
|
|
Packit |
87b8d1 |
{
|
|
Packit |
87b8d1 |
GList *nodes_list = NULL;
|
|
Packit |
87b8d1 |
JsonParser *jparser;
|
|
Packit |
87b8d1 |
GType node_type;
|
|
Packit |
87b8d1 |
|
|
Packit |
87b8d1 |
node_type = G_OBJECT_TYPE (self);
|
|
Packit |
87b8d1 |
|
|
Packit |
87b8d1 |
jparser = json_parser_new ();
|
|
Packit |
87b8d1 |
if (json_parser_load_from_data (jparser, payload, -1, error)) {
|
|
Packit |
87b8d1 |
JsonNode *root_jnode;
|
|
Packit |
87b8d1 |
JsonObject *main_jobject;
|
|
Packit |
87b8d1 |
JsonArray *nodes_jarray;
|
|
Packit |
87b8d1 |
int i = 0;
|
|
Packit |
87b8d1 |
|
|
Packit |
87b8d1 |
root_jnode = json_parser_get_root (jparser);
|
|
Packit |
87b8d1 |
main_jobject = json_node_get_object (root_jnode);
|
|
Packit |
87b8d1 |
nodes_jarray = json_object_get_array_member (main_jobject, "data");
|
|
Packit |
87b8d1 |
for (i = 0; i < json_array_get_length (nodes_jarray); i++) {
|
|
Packit |
87b8d1 |
JsonNode *jnode;
|
|
Packit |
87b8d1 |
GFBGraphNode *node;
|
|
Packit |
87b8d1 |
|
|
Packit |
87b8d1 |
jnode = json_array_get_element (nodes_jarray, i);
|
|
Packit |
87b8d1 |
node = GFBGRAPH_NODE (json_gobject_deserialize (node_type, jnode));
|
|
Packit |
87b8d1 |
nodes_list = g_list_append (nodes_list, node);
|
|
Packit |
87b8d1 |
}
|
|
Packit |
87b8d1 |
}
|
|
Packit |
87b8d1 |
|
|
Packit |
87b8d1 |
g_clear_object (&jparser);
|
|
Packit |
87b8d1 |
|
|
Packit |
87b8d1 |
return nodes_list;
|
|
Packit |
87b8d1 |
}
|