/twitter-glib/twitter-user-list.c

https://github.com/crnt/twitter-glib · C · 260 lines · 184 code · 51 blank · 25 comment · 16 complexity · f80a376f407cb90650f4344a1fcb541c MD5 · raw file

  1. /* twitter-user-list.c: Collection of users
  2. *
  3. * This file is part of Twitter-GLib.
  4. * Copyright (C) 2008 Emmanuele Bassi <ebassi@gnome.org>
  5. *
  6. * This library is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU Lesser General Public License as published
  8. * by the Free Software Foundation, either version 2.1 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. /**
  20. * SECTION:twitter-user-list
  21. * @short_description: A class representing a collection of users
  22. *
  23. * #TwitterUserList is a class collecting a list of #TwitterUser
  24. * instances.
  25. */
  26. #ifdef HAVE_CONFIG_H
  27. #include "config.h"
  28. #endif
  29. #include <string.h>
  30. #include <glib.h>
  31. #include <json-glib/json-glib.h>
  32. #include "twitter-common.h"
  33. #include "twitter-enum-types.h"
  34. #include "twitter-private.h"
  35. #include "twitter-status.h"
  36. #include "twitter-user-list.h"
  37. #include "twitter-user.h"
  38. #define TWITTER_USER_LIST_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TWITTER_TYPE_USER_LIST, TwitterUserListPrivate))
  39. struct _TwitterUserListPrivate
  40. {
  41. GHashTable *user_by_id;
  42. GList *user_list;
  43. };
  44. G_DEFINE_TYPE (TwitterUserList, twitter_user_list, G_TYPE_OBJECT);
  45. static void
  46. twitter_user_list_finalize (GObject *gobject)
  47. {
  48. TwitterUserListPrivate *priv = TWITTER_USER_LIST (gobject)->priv;
  49. g_hash_table_destroy (priv->user_by_id);
  50. g_list_free (priv->user_list);
  51. G_OBJECT_CLASS (twitter_user_list_parent_class)->finalize (gobject);
  52. }
  53. static void
  54. twitter_user_list_class_init (TwitterUserListClass *klass)
  55. {
  56. GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  57. g_type_class_add_private (klass, sizeof (TwitterUserListPrivate));
  58. gobject_class->finalize = twitter_user_list_finalize;
  59. }
  60. static void
  61. twitter_user_list_init (TwitterUserList *user_list)
  62. {
  63. TwitterUserListPrivate *priv;
  64. user_list->priv = priv = TWITTER_USER_LIST_GET_PRIVATE (user_list);
  65. priv->user_by_id = g_hash_table_new_full (NULL, NULL,
  66. NULL,
  67. g_object_unref);
  68. }
  69. static void
  70. twitter_user_list_clean (TwitterUserList *user_list)
  71. {
  72. TwitterUserListPrivate *priv = user_list->priv;
  73. if (priv->user_list)
  74. {
  75. g_list_free (priv->user_list);
  76. priv->user_list = NULL;
  77. }
  78. if (priv->user_by_id)
  79. {
  80. g_hash_table_destroy (priv->user_by_id);
  81. priv->user_by_id = g_hash_table_new_full (NULL, NULL,
  82. NULL,
  83. g_object_unref);
  84. }
  85. }
  86. static void
  87. twitter_user_list_build (TwitterUserList *user_list,
  88. JsonNode *node)
  89. {
  90. TwitterUserListPrivate *priv = user_list->priv;
  91. JsonArray *array;
  92. GList *elements, *l;
  93. GList *list = NULL;
  94. if (!node || JSON_NODE_TYPE (node) != JSON_NODE_ARRAY)
  95. return;
  96. array = json_node_get_array (node);
  97. elements = json_array_get_elements (array);
  98. for (l = elements; l != NULL; l = l->next)
  99. {
  100. JsonNode *element = l->data;
  101. if (JSON_NODE_TYPE (element) == JSON_NODE_OBJECT)
  102. {
  103. TwitterUser *user;
  104. guint user_id;
  105. user = twitter_user_new_from_node (element);
  106. user_id = twitter_user_get_id (user);
  107. if (user_id == 0)
  108. {
  109. g_object_unref (user);
  110. continue;
  111. }
  112. g_hash_table_replace (priv->user_by_id,
  113. GUINT_TO_POINTER (user_id),
  114. g_object_ref_sink (user));
  115. list = g_list_prepend (list, user);
  116. }
  117. }
  118. priv->user_list = g_list_reverse (list);
  119. }
  120. TwitterUserList *
  121. twitter_user_list_new (void)
  122. {
  123. return g_object_new (TWITTER_TYPE_USER_LIST, NULL);
  124. }
  125. TwitterUserList *
  126. twitter_user_list_new_from_data (const gchar *buffer)
  127. {
  128. TwitterUserList *retval;
  129. JsonParser *parser;
  130. GError *parse_error;
  131. g_return_val_if_fail (buffer != NULL, NULL);
  132. retval = twitter_user_list_new ();
  133. parser = json_parser_new ();
  134. parse_error = NULL;
  135. json_parser_load_from_data (parser, buffer, -1, &parse_error);
  136. if (parse_error)
  137. {
  138. g_warning ("Unable to parse data into a user list: %s",
  139. parse_error->message);
  140. g_error_free (parse_error);
  141. }
  142. else
  143. twitter_user_list_build (retval, json_parser_get_root (parser));
  144. g_object_unref (parser);
  145. return retval;
  146. }
  147. gboolean
  148. twitter_user_list_load_from_data (TwitterUserList *user_list,
  149. const gchar *buffer,
  150. GError **error)
  151. {
  152. JsonParser *parser;
  153. GError *parse_error;
  154. gboolean retval = TRUE;
  155. g_return_val_if_fail (TWITTER_IS_USER_LIST (user_list), FALSE);
  156. g_return_val_if_fail (buffer != NULL, FALSE);
  157. twitter_user_list_clean (user_list);
  158. parser = json_parser_new ();
  159. parse_error = NULL;
  160. json_parser_load_from_data (parser, buffer, -1, &parse_error);
  161. if (parse_error)
  162. {
  163. g_set_error (error, TWITTER_ERROR,
  164. TWITTER_ERROR_PARSE_ERROR,
  165. "Parse error (%s)",
  166. parse_error->message);
  167. g_error_free (parse_error);
  168. retval = FALSE;
  169. }
  170. else
  171. twitter_user_list_build (user_list, json_parser_get_root (parser));
  172. g_object_unref (parser);
  173. return retval;
  174. }
  175. guint
  176. twitter_user_list_get_count (TwitterUserList *user_list)
  177. {
  178. g_return_val_if_fail (TWITTER_IS_USER_LIST (user_list), 0);
  179. return g_hash_table_size (user_list->priv->user_by_id);
  180. }
  181. TwitterUser *
  182. twitter_user_list_get_id (TwitterUserList *user_list,
  183. guint id)
  184. {
  185. g_return_val_if_fail (TWITTER_IS_USER_LIST (user_list), NULL);
  186. return g_hash_table_lookup (user_list->priv->user_by_id,
  187. GUINT_TO_POINTER (id));
  188. }
  189. TwitterUser *
  190. twitter_user_list_get_pos (TwitterUserList *user_list,
  191. gint index_)
  192. {
  193. g_return_val_if_fail (TWITTER_IS_USER_LIST (user_list), NULL);
  194. g_return_val_if_fail (ABS (index_) < twitter_user_list_get_count (user_list), NULL);
  195. if (index_ >= 0)
  196. return g_list_nth_data (user_list->priv->user_list, index_);
  197. else
  198. {
  199. guint roll = g_list_length (user_list->priv->user_list);
  200. roll += index_;
  201. return g_list_nth_data (user_list->priv->user_list, roll);
  202. }
  203. }
  204. GList *
  205. twitter_user_list_get_all (TwitterUserList *user_list)
  206. {
  207. g_return_val_if_fail (TWITTER_IS_USER_LIST (user_list), NULL);
  208. return g_list_copy (user_list->priv->user_list);
  209. }