3 * Purple is the legal property of its developers, whose names are too numerous
4 * to list here. Please refer to the COPYRIGHT file distributed with this
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
22 #include "smiley-custom.h"
27 #include <glib/gstdio.h>
30 #define SMILEYS_DEFAULT_FOLDER "custom_smiley"
31 #define SMILEYS_INDEX_FILE "smileys.xml"
33 static gchar
*smileys_dir
;
34 static gchar
*smileys_index
;
36 static PurpleSmileyList
*smileys_list
;
37 static gboolean disable_write
= FALSE
;
39 /*******************************************************************************
41 ******************************************************************************/
44 purple_smiley_custom_load(void)
46 PurpleXmlNode
*root_node
, *profile_node
, *smileyset_node
, *smiley_node
;
51 if (!g_file_test(smileys_index
, G_FILE_TEST_EXISTS
))
54 basename
= g_path_get_basename(smileys_index
);
55 dirname
= g_path_get_dirname(smileys_index
);
56 root_node
= purple_xmlnode_from_file(dirname
, basename
,
57 "custom smileys index", "smiley-custom");
61 g_return_if_fail(root_node
);
63 profile_node
= purple_xmlnode_get_child(root_node
, "profile");
65 purple_xmlnode_free(root_node
);
66 g_return_if_fail(profile_node
);
69 smileyset_node
= purple_xmlnode_get_child(profile_node
, "smiley_set");
70 if (!smileyset_node
) {
71 purple_xmlnode_free(root_node
);
72 g_return_if_fail(smileyset_node
);
75 smiley_node
= purple_xmlnode_get_child(smileyset_node
, "smiley");
77 const gchar
*shortcut
, *file_name
;
79 shortcut
= purple_xmlnode_get_attrib(smiley_node
, "shortcut");
80 file_name
= purple_xmlnode_get_attrib(smiley_node
, "filename");
82 if (shortcut
&& file_name
) {
84 gchar
*file_path
= g_build_filename(
85 smileys_dir
, file_name
, NULL
);
87 smiley
= purple_smiley_new(shortcut
, file_path
);
90 if (purple_smiley_list_add(smileys_list
, smiley
)) {
93 purple_debug_warning("smiley-custom",
94 "Couldn't add '%s' smiley", shortcut
);
96 g_object_unref(smiley
);
99 smiley_node
= purple_xmlnode_get_next_twin(smiley_node
);
102 purple_xmlnode_free(root_node
);
104 purple_debug_info("smiley-custom", "Loaded %d custom smiley(s)",
108 static PurpleXmlNode
*
109 smileys_to_xmlnode(void)
111 PurpleXmlNode
*root_node
, *profile_node
, *smileyset_node
;
115 root_node
= purple_xmlnode_new("smileys");
116 purple_xmlnode_set_attrib(root_node
, "version", "1.0");
118 profile_node
= purple_xmlnode_new("profile");
119 purple_xmlnode_insert_child(root_node
, profile_node
);
120 purple_xmlnode_set_attrib(profile_node
, "name", "Default");
122 smileyset_node
= purple_xmlnode_new("smiley_set");
123 purple_xmlnode_insert_child(profile_node
, smileyset_node
);
125 smileys
= purple_smiley_list_get_all(smileys_list
);
127 for (it
= smileys
; it
; it
= g_list_next(it
)) {
128 PurpleSmiley
*smiley
= PURPLE_SMILEY(it
->data
);
129 PurpleXmlNode
*smiley_node
;
131 smiley_node
= purple_xmlnode_new("smiley");
132 purple_xmlnode_insert_child(smileyset_node
, smiley_node
);
133 purple_xmlnode_set_attrib(smiley_node
, "shortcut",
134 purple_smiley_get_shortcut(smiley
));
135 basename
= g_path_get_basename(purple_image_get_path(
136 PURPLE_IMAGE(smiley
)));
137 purple_xmlnode_set_attrib(smiley_node
, "filename", basename
);
145 purple_smiley_custom_save(void)
147 PurpleXmlNode
*root_node
;
149 GError
*error
= NULL
;
154 root_node
= smileys_to_xmlnode();
155 g_return_if_fail(root_node
!= NULL
);
157 data
= purple_xmlnode_to_formatted_str(root_node
, NULL
);
158 g_return_if_fail(data
!= NULL
);
160 g_file_set_contents(smileys_index
, data
, -1, &error
);
163 purple_xmlnode_free(root_node
);
166 purple_debug_error("smiley-custom",
167 "Error writting custom smileys xml file");
172 purple_smiley_custom_img_checksum(PurpleImage
*img
)
174 g_return_val_if_fail(PURPLE_IS_IMAGE(img
), NULL
);
176 return g_compute_checksum_for_data(G_CHECKSUM_SHA1
,
177 purple_image_get_data(img
),
178 purple_image_get_data_size(img
));
182 /*******************************************************************************
184 ******************************************************************************/
187 purple_smiley_custom_add(PurpleImage
*img
, const gchar
*shortcut
)
189 PurpleSmiley
*existing_smiley
, *smiley
;
190 gchar
*checksum
, *file_path
;
191 gchar file_name
[256];
192 const gchar
*file_ext
;
195 g_return_val_if_fail(PURPLE_IS_IMAGE(img
), NULL
);
197 existing_smiley
= purple_smiley_list_get_by_shortcut(
198 smileys_list
, shortcut
);
202 if (existing_smiley
) {
203 disable_write
= TRUE
;
204 purple_smiley_custom_remove(existing_smiley
);
205 disable_write
= FALSE
;
208 checksum
= purple_smiley_custom_img_checksum(img
);
209 file_ext
= purple_image_get_extension(img
);
210 if (file_ext
== NULL
|| g_strcmp0("icon", file_ext
) == 0) {
211 purple_debug_warning("smiley-custom", "Invalid image type");
215 g_snprintf(file_name
, sizeof(file_name
), "%s.%s", checksum
, file_ext
);
218 file_path
= g_build_filename(smileys_dir
, file_name
, NULL
);
220 if (!purple_image_save(img
, file_path
)) {
221 purple_debug_error("smiley-custom", "Failed writing smiley "
222 "file %s", file_path
);
229 smiley
= purple_smiley_new(shortcut
, file_path
);
231 succ
= purple_smiley_list_add(smileys_list
, smiley
);
232 g_object_unref(smiley
);
235 purple_debug_error("smiley-custom", "Failed adding a smiley");
237 purple_smiley_custom_save();
243 purple_smiley_custom_remove(PurpleSmiley
*smiley
)
245 PurpleSmiley
*existing_smiley
;
246 const gchar
*smiley_shortcut
, *path
;
247 GList
*other_smileys
, *it
;
250 g_return_if_fail(PURPLE_IS_SMILEY(smiley
));
252 smiley_shortcut
= purple_smiley_get_shortcut(smiley
);
253 existing_smiley
= purple_smiley_list_get_by_shortcut(
254 smileys_list
, smiley_shortcut
);
255 if (existing_smiley
== NULL
)
257 if (existing_smiley
!= smiley
) {
258 purple_debug_warning("smiley-custom", "Smiley is not in store");
262 g_object_ref(smiley
);
263 purple_smiley_list_remove(smileys_list
, smiley
);
265 path
= purple_image_get_path(PURPLE_IMAGE(smiley
));
267 other_smileys
= purple_smiley_list_get_unique(smileys_list
);
269 for (it
= other_smileys
; it
; it
= g_list_next(it
)) {
270 PurpleSmiley
*other
= it
->data
;
271 const gchar
*other_path
= purple_image_get_path(PURPLE_IMAGE(other
));
272 if (g_strcmp0(other_path
, path
) == 0) {
277 g_list_free(other_smileys
);
282 g_object_unref(smiley
);
284 purple_smiley_custom_save();
288 purple_smiley_custom_get_list(void)
294 /*******************************************************************************
295 * Custom smiley subsystem
296 ******************************************************************************/
299 _purple_smiley_custom_init(void)
303 smileys_dir
= g_build_filename(purple_user_dir(),
304 SMILEYS_DEFAULT_FOLDER
, NULL
);
305 smileys_index
= g_build_filename(purple_user_dir(),
306 SMILEYS_INDEX_FILE
, NULL
);
307 smileys_list
= purple_smiley_list_new();
309 ret
= g_mkdir(smileys_dir
, S_IRUSR
| S_IWUSR
| S_IXUSR
);
310 if (ret
!= 0 && errno
!= EEXIST
) {
311 purple_debug_error("smiley-custom", "Failed creating custom "
312 "smileys directory: %s (%d)", g_strerror(errno
), errno
);
315 purple_smiley_custom_load();
319 _purple_smiley_custom_uninit(void)
322 g_free(smileys_index
);
323 g_object_unref(smileys_list
);