Changeset 15
- Timestamp:
- 11/17/06 14:08:54 (2 years ago)
- Files:
-
- maemo-blog/trunk/Makefile (modified) (4 diffs)
- maemo-blog/trunk/blog-blogger.c (modified) (2 diffs)
- maemo-blog/trunk/blog-metaweblog.c (modified) (21 diffs)
- maemo-blog/trunk/debian/changelog (modified) (1 diff)
- maemo-blog/trunk/maemo-blog.desktop (modified) (1 diff)
- maemo-blog/trunk/maemo-blog.png (added)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
maemo-blog/trunk/Makefile
r12 r15 19 19 INCLUDEDIR := $(DESTDIR)/usr/include 20 20 DESKTOPDIR := $(DESTDIR)/usr/share/applications/hildon 21 PIXMAPDIR := $(DESTDIR)/usr/share/pixmaps 21 22 22 23 TOPDIR := $(shell /bin/pwd) … … 55 56 maemo_blog_HEADERS := blog.h blog-plugin.h plugin-loader.h accounts.h login.h gui.h 56 57 maemo_blog_DESKTOP := maemo-blog.desktop 58 maemo_blog_PIXMAPS := maemo-blog.png 57 59 58 libmetaweblog_la_CFLAGS += $(CFLAGS) `pkg-config glib-2.0 --cflags` `xmlrpc-c-config client--cflags`59 libmetaweblog_la_LDFLAGS = ` xmlrpc-c-config client--libs` -module -shared -rpath $(LIBDIR) -avoid-version60 libmetaweblog_la_CFLAGS += $(CFLAGS) `pkg-config glib-2.0 libsoup-2.2 --cflags` 61 libmetaweblog_la_LDFLAGS = `pkg-config glib-2.0 libsoup-2.2 --libs` -module -shared -rpath $(LIBDIR) -avoid-version 60 62 libmetaweblog_la_SOURCES := blog-metaweblog.c 61 63 libmetaweblog_la_HEADERS := blog-plugin.h … … 70 72 maemo_blog_DIR := $(BINDIR) 71 73 maemo_blog_DESKTOPDIR := $(DESKTOPDIR) 74 maemo_blog_PIXMAPDIR := $(PIXMAPDIR) 72 75 73 76 .PHONY: all … … 115 118 @if [ x != "x${$(subst .,_,$(patsubst %.install,%,$@))_PC}" ]; then $(INSTALL_DIR) ${$(subst .,_,$(patsubst %.install,%,$@))_PCDIR}; $(INSTALL_DATA) ${$(subst .,_,$(patsubst %.install,%,$@))_PC} ${$(subst .,_,$(patsubst %.install,%,$@))_PCDIR}; fi 116 119 @if [ x != "x${$(subst .,_,$(patsubst %.install,%,$@))_DESKTOP}" ]; then $(INSTALL_DIR) ${$(subst .,_,$(patsubst %.install,%,$@))_DESKTOPDIR}; $(INSTALL_DATA) ${$(subst .,_,$(patsubst %.install,%,$@))_DESKTOP} ${$(subst .,_,$(patsubst %.install,%,$@))_DESKTOPDIR}; fi 120 @if [ x != "x${$(subst .,_,$(patsubst %.install,%,$@))_PIXMAPS}" ]; then $(INSTALL_DIR) ${$(subst .,_,$(patsubst %.install,%,$@))_PIXMAPDIR}; $(INSTALL_DATA) ${$(subst .,_,$(patsubst %.install,%,$@))_PIXMAPS} ${$(subst .,_,$(patsubst %.install,%,$@))_PIXMAPDIR}; fi 117 121 @if [ x != "x${$(subst .,_,$(patsubst %.install,%,$@))_INCLUDES}" ]; then $(INSTALL_DIR) ${$(subst .,_,$(patsubst %.install,%,$@))_INCLUDEDIR}; $(INSTALL_DATA) ${$(subst .,_,$(patsubst %.install,%,$@))_INCLUDES} ${$(subst .,_,$(patsubst %.install,%,$@))_INCLUDEDIR}; fi 118 122 maemo-blog/trunk/blog-blogger.c
r5 r15 142 142 (void)method_name; 143 143 (void)param_array; 144 145 die_if_fault_occurred(fault); 144 146 147 if (xmlrpc_value_type(blogs) == XMLRPC_TYPE_ARRAY) { 145 148 size = xmlrpc_array_size(fault, blogs); 146 149 die_if_fault_occurred(fault); … … 164 167 } 165 168 retval[i] = NULL; 169 } else { 170 retval = g_new0(Blog *, 2); 171 gchar *blogid = NULL, *name = NULL; 172 xmlrpc_parse_value(fault, blogs, "{s:s,s:s,*}", 173 "blogid", &blogid, 174 "blogName", &name); 175 retval[0] = g_new0(Blog, 1); 176 retval[0]->url = g_strdup(clo->uri); 177 retval[0]->user = g_strdup(clo->user); 178 retval[0]->pass = g_strdup(clo->pass); 179 retval[0]->id = g_strdup(blogid); 180 retval[0]->name = g_strdup(name); 181 retval[0]->plugin = clo->self; 182 retval[0]->posts = NULL; 183 retval[1] = NULL; 184 } 166 185 167 186 clo->cb(retval, clo->user_data); maemo-blog/trunk/blog-metaweblog.c
r13 r15 2 2 #include <stdio.h> 3 3 #include <glib.h> 4 #include <xmlrpc.h> 5 #include <xmlrpc_client.h> 4 #include <glib/gthread.h> 5 #include <libsoup/soup-session-async.h> 6 #include <libsoup/soup-xmlrpc-message.h> 7 #include <libsoup/soup-xmlrpc-response.h> 6 8 #include <string.h> 7 9 8 10 #include "blog-plugin.h" 9 11 10 #define die_if_fault_occurred(x) die_if_fault(x, __FUNCTION__, __LINE__)11 12 12 struct MetaweblogPluginData { 13 xmlrpc_client *client; 14 xmlrpc_env env; 13 SoupSession *session; 15 14 }; 16 17 static gboolean _event_loop(gpointer user_data)18 {19 struct MetaweblogPluginData *data = user_data;20 21 xmlrpc_client_event_loop_finish_timeout(data->client, 20);22 23 return TRUE;24 }25 15 26 16 static BlogCategory *category_lookup(Blog *blog, const gchar *name) … … 39 29 return NULL; 40 30 } 41 42 /* We're a command-line utility, so we abort if an error occurs. */43 static void die_if_fault (xmlrpc_env *env, const char *func, unsigned int line)44 {45 if (env->fault_occurred) {46 fprintf(stderr, "%s:%u: XML-RPC Fault #%d: %s\n",47 func, line,48 env->fault_code, env->fault_string);49 exit(1);50 }51 }52 53 31 54 32 struct BlogMetaweblogConnectedClosure { … … 61 39 gchar *pass; 62 40 }; 63 static void _blog_metaweblog_connected(const char *server_url, 64 const char *method_name, 65 xmlrpc_value *param_array, 66 void *user_data, 67 xmlrpc_env *fault, 68 xmlrpc_value *result); 41 static void _blog_metaweblog_connected(SoupMessage *message, 42 gpointer user_data); 69 43 static gboolean blog_metaweblog_connect(BlogPlugin *plugin, 70 44 const gchar *uri, const gchar *user, … … 79 53 gboolean new_post; 80 54 }; 81 static void _blog_metaweblog_posted(const char *server_url, 82 const char *method_name, 83 xmlrpc_value *param_array, 84 void *user_data, 85 xmlrpc_env *fault, 86 xmlrpc_value *result); 55 static void _blog_metaweblog_posted(SoupMessage *message, 56 gpointer user_data); 87 57 static gboolean blog_metaweblog_new_post(Blog *blog, BlogPost *post, 88 58 gboolean publish, BlogPostCb cb, gpointer user_data); … … 97 67 }; 98 68 99 static void _blog_metaweblog_got_categories(const char *server_url, 100 const char *method_name, 101 xmlrpc_value *param_array, 102 void *user_data, 103 xmlrpc_env *fault, 104 xmlrpc_value *result); 69 static void _blog_metaweblog_got_categories(SoupMessage *message, 70 gpointer user_data); 105 71 static void blog_metaweblog_get_categories(Blog *blog, BlogFetchCb cb, gpointer user_data); 106 static void _blog_metaweblog_got_recent(const char *server_url, 107 const char *method_name, 108 xmlrpc_value *param_array, 109 void *user_data, 110 xmlrpc_env *fault, 111 xmlrpc_value *result); 72 static void _blog_metaweblog_got_recent(SoupMessage *message, 73 gpointer user_data); 112 74 static void blog_metaweblog_get_recent(Blog *blog, BlogFetchCb cb, gpointer user_data); 113 75 static void blog_metaweblog_unload(BlogPlugin *plugin); … … 121 83 gboolean new_post; 122 84 }; 123 static void _blog_metaweblog_uploaded(const char *server_url, 124 const char *method_name, 125 xmlrpc_value *param_array, 126 void *user_data, 127 xmlrpc_env *fault, 128 xmlrpc_value *result); 85 static void _blog_metaweblog_uploaded(SoupMessage *message, 86 gpointer user_data); 129 87 static gboolean blog_metaweblog_upload_image(Blog *blog, const gchar *image_name, 130 88 const gchar *mime_type, … … 137 95 { 138 96 BlogPlugin *retval = g_new0(BlogPlugin, 1); 139 struct xmlrpc_curl_xportparms transportParms;140 struct xmlrpc_clientparms clientParms;141 97 struct MetaweblogPluginData *data; 142 143 memset(&transportParms, 0, sizeof(transportParms));144 memset(&clientParms, 0, sizeof(clientParms));145 146 clientParms.transport = "curl";147 clientParms.transportparmsP = (struct xmlrpc_xportparms *)&transportParms;148 clientParms.transportparm_size = XMLRPC_CXPSIZE(no_ssl_verifyhost);149 150 transportParms.no_ssl_verifypeer = 1;151 transportParms.no_ssl_verifyhost = 1;152 98 153 99 retval->connect = blog_metaweblog_connect; … … 161 107 retval->name = g_strdup("MetaWebLog"); 162 108 retval->plugin_data = data = g_new0(struct MetaweblogPluginData, 1); 163 xmlrpc_env_init(&data->env); 164 xmlrpc_client_setup_global_const(&data->env); 165 xmlrpc_client_create(&data->env, XMLRPC_CLIENT_NO_FLAGS, (char *)"maemo-blog", (char *)"0.0.1", &clientParms, XMLRPC_CPSIZE(transportparm_size), &data->client); 166 die_if_fault_occurred(&data->env); 109 110 if (!g_thread_supported()) { 111 g_thread_init(NULL); 112 } 113 114 data->session = soup_session_async_new(); 167 115 return retval; 168 116 } 169 117 170 static void _blog_metaweblog_connected(const char *server_url, 171 const char *method_name, 172 xmlrpc_value *param_array, 173 void *user_data, 174 xmlrpc_env *fault, 175 xmlrpc_value *blogs) 118 static void _blog_metaweblog_connected(SoupMessage *message, 119 gpointer user_data) 176 120 { 177 121 struct BlogMetaweblogConnectedClosure *clo = (struct BlogMetaweblogConnectedClosure *)user_data; 178 122 Blog **retval = NULL; 179 guint i, size; 180 181 (void)server_url; 182 (void)method_name; 183 (void)param_array; 184 185 size = xmlrpc_array_size(fault, blogs); 186 die_if_fault_occurred(fault); 187 188 retval = g_new0(Blog *, size + 1); 189 190 for (i = 0; i < size; i++) { 191 xmlrpc_value *blog = xmlrpc_array_get_item(fault, blogs, i); 192 gchar *blogid = NULL, *name = NULL; 193 xmlrpc_parse_value(fault, blog, "{s:s,s:s,*}", 194 "blogid", &blogid, 195 "blogName", &name); 196 retval[i] = g_new0(Blog, 1); 197 retval[i]->url = g_strdup(clo->uri); 198 retval[i]->user = g_strdup(clo->user); 199 retval[i]->pass = g_strdup(clo->pass); 200 retval[i]->id = g_strdup(blogid); 201 retval[i]->name = g_strdup(name); 202 retval[i]->plugin = clo->self; 203 retval[i]->posts = NULL; 204 } 205 retval[i] = NULL; 123 SoupXmlrpcResponse *response = soup_xmlrpc_message_parse_response( 124 SOUP_XMLRPC_MESSAGE(message)); 125 126 if (soup_xmlrpc_response_is_fault(response)) { 127 xmlChar *rsp = soup_xmlrpc_response_to_string(response); 128 g_free(rsp); 129 } 130 SoupXmlrpcValue *value = soup_xmlrpc_response_get_value(response); 131 GSList *blogs = NULL; 132 guint count = 0; 133 134 SoupXmlrpcValueArrayIterator *iter; 135 136 soup_xmlrpc_value_array_get_iterator(value, &iter); 137 138 while (iter) { 139 Blog *blog = g_new0(Blog, 1); 140 GHashTable *hash; 141 SoupXmlrpcValue *val; 142 SoupXmlrpcValue *array_val; 143 144 soup_xmlrpc_value_array_iterator_get_value(iter, &array_val); 145 146 soup_xmlrpc_value_get_struct(array_val, &hash); 147 148 val = g_hash_table_lookup(hash, "blogid"); 149 soup_xmlrpc_value_get_string(val, &blog->id); 150 val = g_hash_table_lookup(hash, "blogName"); 151 soup_xmlrpc_value_get_string(val, &blog->name); 152 blog->url = g_strdup(clo->uri); 153 blog->user = g_strdup(clo->user); 154 blog->pass = g_strdup(clo->pass); 155 blog->plugin = clo->self; 156 157 blogs = g_slist_prepend(blogs, blog); 158 count++; 159 160 iter = soup_xmlrpc_value_array_iterator_next(iter); 161 } 162 163 retval = g_new0(Blog *, count + 1); 164 retval[count] = NULL; 165 166 while (blogs) { 167 retval[--count] = blogs->data; 168 blogs = g_slist_delete_link(blogs, blogs); 169 } 206 170 207 171 clo->cb(retval, clo->user_data); 208 g_source_remove(clo->timeout_id);209 172 g_free(clo->uri); 210 173 g_free(clo->user); … … 219 182 struct BlogMetaweblogConnectedClosure *clo = g_new0(struct BlogMetaweblogConnectedClosure, 1); 220 183 struct MetaweblogPluginData *data = plugin->plugin_data; 184 SoupXmlrpcMessage *msg; 221 185 222 186 clo->cb = cb; … … 227 191 clo->self = plugin; 228 192 229 xmlrpc_client_start_rpcf(&data->env, 230 data->client, 231 (gchar *)uri, 232 (char *)"blogger.getUsersBlogs", 233 _blog_metaweblog_connected, 234 clo, 235 (char *)"(sss)", 236 "0123456789ABCDEF", 237 user, 193 msg = soup_xmlrpc_message_new(uri); 194 soup_xmlrpc_message_start_call(msg, 195 "blogger.getUsersBlogs"); 196 soup_xmlrpc_message_start_param(msg); 197 soup_xmlrpc_message_write_string(msg, 198 "0123456789ABCDEF"); 199 soup_xmlrpc_message_end_param(msg); 200 soup_xmlrpc_message_start_param(msg); 201 soup_xmlrpc_message_write_string(msg, 202 user); 203 soup_xmlrpc_message_end_param(msg); 204 soup_xmlrpc_message_start_param(msg); 205 soup_xmlrpc_message_write_string(msg, 238 206 pass); 239 240 clo->timeout_id = g_timeout_add(500, _event_loop, data); 207 soup_xmlrpc_message_end_param(msg); 208 soup_xmlrpc_message_end_call(msg); 209 soup_xmlrpc_message_persist(msg); 210 211 soup_session_queue_message(data->session, SOUP_MESSAGE(msg), 212 _blog_metaweblog_connected, clo); 241 213 242 214 return TRUE; 243 215 } 244 216 245 static void _blog_metaweblog_posted(const char *server_url, 246 const char *method_name, 247 xmlrpc_value *param_array, 248 void *user_data, 249 xmlrpc_env *fault, 250 xmlrpc_value *retval) 217 static void _blog_metaweblog_posted(SoupMessage *message, 218 gpointer user_data) 251 219 { 252 220 struct BlogMetaweblogPostedClosure *clo = (struct BlogMetaweblogPostedClosure *)user_data; 253 221 gboolean status = TRUE; 254 gintnumeric_id = 0;222 long numeric_id = 0; 255 223 gchar *string_id = NULL; 256 257 (void)server_url;258 (void)method_name; 259 (void)param_array;224 SoupXmlrpcResponse *response = soup_xmlrpc_message_parse_response( 225 SOUP_XMLRPC_MESSAGE(message)); 226 227 SoupXmlrpcValue *value = soup_xmlrpc_response_get_value(response); 260 228 261 229 if (clo->new_post) { 262 switch (xmlrpc_value_type(retval)) { 263 case XMLRPC_TYPE_INT: 264 xmlrpc_parse_value(fault, retval, "i", &numeric_id); 230 switch (soup_xmlrpc_value_get_type(value)) { 231 case SOUP_XMLRPC_VALUE_TYPE_INT: 232 soup_xmlrpc_value_get_int(value, 233 &numeric_id); 265 234 break; 266 case XMLRPC_TYPE_STRING: 267 xmlrpc_parse_value(fault, retval, "s", &string_id); 235 case SOUP_XMLRPC_VALUE_TYPE_STRING: 236 soup_xmlrpc_value_get_string(value, 237 &string_id); 268 238 break; 269 239 default: … … 271 241 break; 272 242 } 273 die_if_fault_occurred(fault);274 243 275 244 if (string_id) { 276 clo->post->id = g_strdup(string_id);245 clo->post->id = string_id; 277 246 } else { 278 clo->post->id = g_strdup_printf("% d\n", numeric_id);247 clo->post->id = g_strdup_printf("%ld\n", numeric_id); 279 248 } 280 249 281 250 clo->blog->posts = g_slist_prepend(clo->blog->posts, clo->post); 282 251 } else { 283 xmlrpc_parse_value(fault, retval, "b", &status);252 soup_xmlrpc_value_get_boolean(value, &status); 284 253 } 285 254 clo->cb(clo->blog, clo->post, status, clo->user_data); 286 g_source_remove(clo->timeout_id);287 255 g_free(clo); 288 256 } … … 291 259 gboolean publish, BlogPostCb cb, gpointer user_data) 292 260 { 293 xmlrpc_value *array;294 xmlrpc_value *stru;295 261 GSList *iter; 296 262 struct BlogMetaweblogPostedClosure *clo; 297 263 struct MetaweblogPluginData *data = blog->plugin->plugin_data; 264 SoupXmlrpcMessage *msg; 298 265 299 266 if (!post || !post->content) { … … 308 275 clo->user_data = user_data; 309 276 310 array = xmlrpc_array_new(&data->env); 311 die_if_fault_occurred(&data->env); 312 277 msg = soup_xmlrpc_message_new(blog->url); 278 soup_xmlrpc_message_start_call(msg, "metaWeblog.newPost"); 279 soup_xmlrpc_message_start_param(msg); 280 soup_xmlrpc_message_write_string(msg, blog->id); 281 soup_xmlrpc_message_end_param(msg); 282 soup_xmlrpc_message_start_param(msg); 283 soup_xmlrpc_message_write_string(msg, blog->user); 284 soup_xmlrpc_message_end_param(msg); 285 soup_xmlrpc_message_start_param(msg); 286 soup_xmlrpc_message_write_string(msg, blog->pass); 287 soup_xmlrpc_message_end_param(msg); 288 soup_xmlrpc_message_start_param(msg); 289 soup_xmlrpc_message_start_struct(msg); 290 soup_xmlrpc_message_start_member(msg, 291 "title"); 292 soup_xmlrpc_message_write_string(msg, 293 post->title); 294 soup_xmlrpc_message_end_member(msg); 295 soup_xmlrpc_message_start_member(msg, 296 "description"); 297 soup_xmlrpc_message_write_string(msg, 298 post->content); 299 soup_xmlrpc_message_end_member(msg); 300 soup_xmlrpc_message_start_member(msg, 301 "category"); 302 soup_xmlrpc_message_start_array(msg); 313 303 for (iter = post->categories; iter; iter = iter->next) 314 304 { 315 305 BlogCategory *cat = (BlogCategory *)iter->data; 316 xmlrpc_value *val = xmlrpc_build_value(&data->env, "s", 317 cat->name); 318 die_if_fault_occurred(&data->env); 319 xmlrpc_array_append_item(&data->env, array, val); 320 die_if_fault_occurred(&data->env); 321 } 322 323 stru = xmlrpc_struct_new(&data->env); 324 xmlrpc_struct_set_value(&data->env, 325 stru, 326 "title", 327 xmlrpc_string_new(&data->env, post->title)); 328 xmlrpc_struct_set_value(&data->env, 329 stru, 330 "description", 331 xmlrpc_string_new(&data->env, post->content)); 332 xmlrpc_struct_set_value(&data->env, 333 stru, 334 "category", 335 array); 336 xmlrpc_struct_set_value(&data->env, 337 stru, 338 "categories", 339 array); 306 soup_xmlrpc_message_write_string(msg, cat->id); 307 } 308 soup_xmlrpc_message_end_array(msg); 309 soup_xmlrpc_message_end_member(msg); 310 soup_xmlrpc_message_start_member(msg, 311 "categories"); 312 soup_xmlrpc_message_start_array(msg); 313 for (iter = post->categories; iter; iter = iter->next) 314 { 315 BlogCategory *cat = (BlogCategory *)iter->data; 316 soup_xmlrpc_message_write_string(msg, cat->id); 317 } 318 soup_xmlrpc_message_end_array(msg); 319 soup_xmlrpc_message_end_member(msg); 340 320 for (iter = post->extra_fields; iter; iter = iter->next) { 341 321 BlogParameter *parm = iter->data; 342 xmlrpc_value *value = NULL;322 soup_xmlrpc_message_start_member(msg, parm->name); 343 323 switch (G_VALUE_TYPE(&parm->value)) { 344 324 case G_TYPE_STRING: 345 value = xmlrpc_string_new(&data->env,325 soup_xmlrpc_message_write_string(msg, 346 326 g_value_get_string( 347 327 &parm->value)); 348 328 break; 349 329 case G_TYPE_INT: 350 value = xmlrpc_int_new(&data->env,330 soup_xmlrpc_message_write_int(msg, 351 331 g_value_get_int( 352 332 &parm->value)); 353 333 break; 354 334 case G_TYPE_UINT: 355 value = xmlrpc_int_new(&data->env,335 soup_xmlrpc_message_write_int(msg, 356 336 (int)g_value_get_uint( 357 337 &parm->value)); 358 338 break; 359 339 case G_TYPE_BOOLEAN: 360 value = xmlrpc_bool_new(&data->env,340 soup_xmlrpc_message_write_boolean(msg, 361 341 g_value_get_boolean( 362 342 &parm->value)); … … 365 345 break; 366 346 } 367 if (value) { 368 xmlrpc_struct_set_value(&data->env, 369 stru, 370 parm->name, 371 value); 372 } 373 } 374 375 xmlrpc_client_start_rpcf(&data->env, 376 data->client, 377 blog->url, (char *)"metaWeblog.newPost", 378 _blog_metaweblog_posted, 379 clo, 380 (char *)"(sssVb)", 381 blog->id, 382 blog->user, 383 blog->pass, 384 stru, 385 publish); 386 387 clo->timeout_id = g_timeout_add(500, _event_loop, data); 347 soup_xmlrpc_message_end_member(msg); 348 } 349 soup_xmlrpc_message_end_struct(msg); 350 soup_xmlrpc_message_end_param(msg); 351 soup_xmlrpc_message_start_param(msg); 352 soup_xmlrpc_message_write_boolean(msg, publish); 353 soup_xmlrpc_message_end_param(msg); 354 soup_xmlrpc_message_end_call(msg); 355 soup_xmlrpc_message_persist(msg); 356 357 soup_session_queue_message(data->session, SOUP_MESSAGE(msg), 358 _blog_metaweblog_posted, clo); 388 359 389 360 return TRUE; … … 393 364 gboolean publish, BlogPostCb cb, gpointer user_data) 394 365 { 395 xmlrpc_env env;396 xmlrpc_value *array;397 366 GSList *iter; 398 367 struct BlogMetaweblogPostedClosure *clo; 399 368 struct MetaweblogPluginData *data = blog->plugin->plugin_data; 369 SoupXmlrpcMessage *msg; 400 370 401 371 if (!post || !post->content || !post->id) { … … 410 380 clo->new_post = FALSE; 411 381 412 xmlrpc_env_init(&env); 413 array = xmlrpc_build_value(&env, "()"); 414 die_if_fault_occurred(&env); 415 382 msg = soup_xmlrpc_message_new(blog->url); 383 soup_xmlrpc_message_start_call(msg, "metaWeblog.editPost"); 384 soup_xmlrpc_message_start_param(msg); 385 soup_xmlrpc_message_write_string(msg, post->id); 386 soup_xmlrpc_message_end_param(msg); 387 soup_xmlrpc_message_start_param(msg); 388 soup_xmlrpc_message_write_string(msg, blog->user); 389 soup_xmlrpc_message_end_param(msg); 390 soup_xmlrpc_message_start_param(msg); 391 soup_xmlrpc_message_write_string(msg, blog->pass); 392 soup_xmlrpc_message_end_param(msg); 393 soup_xmlrpc_message_start_param(msg); 394 soup_xmlrpc_message_start_struct(msg); 395 soup_xmlrpc_message_start_member(msg, 396 "title"); 397 soup_xmlrpc_message_write_string(msg, 398 post->title); 399 soup_xmlrpc_message_end_member(msg); 400 soup_xmlrpc_message_start_member(msg, 401 "description"); 402 soup_xmlrpc_message_write_string(msg, 403 post->content); 404 soup_xmlrpc_message_end_member(msg); 405 soup_xmlrpc_message_start_member(msg, 406 "category"); 407 soup_xmlrpc_message_start_array(msg); 416 408 for (iter = post->categories; iter; iter = iter->next) 417 409 { 418 410 BlogCategory *cat = (BlogCategory *)iter->data; 419 xmlrpc_value *val = xmlrpc_build_value(&env, "s", 420 cat->name); 421 die_if_fault_occurred(&env); 422 xmlrpc_array_append_item(&env, array, val); 423 die_if_fault_occurred(&env); 424 } 425 426 xmlrpc_client_start_rpcf(&data->env, 427 data->client, 428 blog->url, 429 (char *)"metaWeblog.editPost", 430 _blog_metaweblog_posted, 431 clo, 432 (char *)"(sss{s:s,s:s,s:V,s:V}b)", 433 post->id, 434 blog->user, 435 blog->pass, 436 "title", 437 post->title, 438 "description", 439 post->content, 440 "category", 441 array, 442 "categories", 443 array, 444 publish); 445 446 xmlrpc_env_clean(&env); 447 clo->timeout_id = g_timeout_add(500, _event_loop, data); 411 soup_xmlrpc_message_write_string(msg, cat->id); 412 } 413 soup_xmlrpc_message_end_array(msg); 414 soup_xmlrpc_message_end_member(msg); 415 soup_xmlrpc_message_start_member(msg, 416 "categories"); 417 soup_xmlrpc_message_start_array(msg); 418 for (iter = post->categories; iter; iter = iter->next) 419 { 420 BlogCategory *cat = (BlogCategory *)iter->data; 421 soup_xmlrpc_message_write_string(msg, cat->id); 422 } 423 soup_xmlrpc_message_end_array(msg); 424 soup_xmlrpc_message_end_member(msg); 425 for (iter = post->extra_fields; iter; iter = iter->next) { 426 BlogParameter *parm = iter->data; 427 soup_xmlrpc_message_start_member(msg, parm->name); 428 switch (G_VALUE_TYPE(&parm->value)) { 429 case G_TYPE_STRING: 430 soup_xmlrpc_message_write_string(msg, 431 g_value_get_string( 432 &parm->value)); 433 break; 434 case G_TYPE_INT: 435 soup_xmlrpc_message_write_int(msg, 436 g_value_get_int( 437 &parm->value)); 438 break; 439 case G_TYPE_UINT: 440 soup_xmlrpc_message_write_int(msg, 441 (int)g_value_get_uint( 442 &parm->value)); 443 break; 444 case G_TYPE_BOOLEAN: 445 soup_xmlrpc_message_write_boolean(msg, 446 g_value_get_boolean( 447 &parm->value)); 448 break; 449 default: 450 break; 451 } 452 soup_xmlrpc_message_end_member(msg); 453 } 454 soup_xmlrpc_message_end_struct(msg); 455 soup_xmlrpc_message_end_param(msg); 456 soup_xmlrpc_message_start_param(msg); 457 soup_xmlrpc_message_write_boolean(msg, publish); 458 soup_xmlrpc_message_end_param(msg); 459 soup_xmlrpc_message_end_call(msg); 460 soup_xmlrpc_message_persist(msg); 461 462 soup_session_queue_message(data->session, SOUP_MESSAGE(msg), 463 _blog_metaweblog_posted, clo); 448 464 449 465 return TRUE; 450 466 } 451 467 452 static void _blog_metaweblog_got_categories(const char *server_url, 453 const char *method_name, 454 xmlrpc_value *param_array, 455 void *user_data, 456 xmlrpc_env *fault, 457 xmlrpc_value *retval) 468 static void _add_category(gpointer key, gpointer value, gpointer user_data) 469 { 470 GSList **categories = user_data; 471 gchar *id = key; 472 gchar *name = NULL; 473 SoupXmlrpcValue *val = value; 474 GHashTable *table; 475 BlogCategory *category = 476 g_new0(BlogCategory, 1); 477 478 soup_xmlrpc_value_get_struct(val, &table); 479 val = g_hash_table_lookup(table, "description"); 480 if (val) { 481 soup_xmlrpc_value_get_string(val, &name); 482 } 483 484 category->id = g_strdup(id); 485 category->name = name ? name : g_strdup(id); 486 487 *categories = g_slist_append(*categories, category); 488 } 489 490 static void _blog_metaweblog_got_categories(SoupMessage *message, 491 gpointer user_data) 458 492 { 459 493 struct BlogMetaweblogFetchedClosure *clo = (struct BlogMetaweblogFetchedClosure *)user_data; 460 size_t size, i; 461 462 (void)server_url; 463 (void)method_name; 464 (void)param_array; 465 466 if (xmlrpc_value_type(retval) == XMLRPC_TYPE_ARRAY) { 467 size = xmlrpc_array_size(fault, retval); 468 die_if_fault_occurred(fault); 469 470 for (i = 0; i < size; i++) { 471 xmlrpc_value *cat = xmlrpc_array_get_item(fault, retval, i); 472 gchar *id, *name; 473 474 xmlrpc_parse_value(fault, cat, "{s:s,s:s,*}", 475 "categoryId", &id, 476 "description", &name); 477 478 if (id && name) { 479 BlogCategory *category = g_new0(BlogCategory, 1); 480 category->id = g_strdup(id); 481 category->name = g_strdup(name); 482 483 clo->blog->categories = g_slist_append(clo->blog->categories, category); 494 495 SoupXmlrpcResponse *response = soup_xmlrpc_message_parse_response( 496 SOUP_XMLRPC_MESSAGE(message)); 497 SoupXmlrpcValue *value = soup_xmlrpc_response_get_value(response); 498 499 if (soup_xmlrpc_value_get_type(value) == SOUP_XMLRPC_VALUE_TYPE_ARRAY) { 500 SoupXmlrpcValueArrayIterator *iter; 501 SoupXmlrpcValue *subvalue; 502 503 soup_xmlrpc_value_array_get_iterator(value, &iter); 504 505 while (iter) { 506 soup_xmlrpc_value_array_iterator_get_value(iter,&subvalue); 507 GHashTable *table; 508 gchar *id = NULL, *name = NULL; 509 soup_xmlrpc_value_get_struct(subvalue, &table); 510 511 subvalue = g_hash_table_lookup(table, 512 "categoryId"); 513 if (subvalue) { 514 soup_xmlrpc_value_get_string(subvalue, 515 &id); 484 516 } 485 } 486 } else { 487 size = xmlrpc_struct_size(fault, retval); 488 die_if_fault_occurred(fault); 489 490 for (i = 0; i < size; i++) { 491 xmlrpc_value *key = NULL, *val = NULL; 492 const gchar *id = NULL, *name = NULL; 493 494 xmlrpc_struct_read_member(fault, retval, i, 495 &key, &val); 496 497 xmlrpc_read_string(fault, key, 498 &id); 499 xmlrpc_parse_value(fault, val, "{s:s,*}", 500 "description", &name); 501 if (id && name) { 517 subvalue = g_hash_table_lookup(table, 518 "description"); 519 if (subvalue) { 520 soup_xmlrpc_value_get_string(subvalue, 521 &name); 522 } 523 if (name) { 502 524 BlogCategory *category = 503 525 g_new0(BlogCategory, 1); 504 category->id = g_strdup(id); 505 category->name = g_strdup(name); 506 507 clo->blog->categories = g_slist_append(clo->blog->categories, category); 526 category->id = id ? id : g_strdup(name); 527 category->name = name; 528 529 clo->blog->categories = g_slist_append( 530 clo->blog->categories, 531 category); 508 532 } 509 } 510 } 511 512 513 514 g_source_remove(clo->timeout_id); 533 iter = soup_xmlrpc_value_array_iterator_next(iter); 534 } 535 } else { 536 GHashTable *table; 537 soup_xmlrpc_value_get_struct(value, &table); 538 g_hash_table_foreach(table, _add_category, 539 &clo->blog->categories); 540 } 541 515 542 clo->cb(clo->blog, clo->user_data); 516 543 g_free(clo); … … 521 548 struct BlogMetaweblogFetchedClosure *clo = g_new0(struct BlogMetaweblogFetchedClosure, 1); 522 549 struct MetaweblogPluginData *data = blog->plugin->plugin_data; 550 SoupXmlrpcMessage *msg; 523 551 clo->blog = blog; 524 552 clo->cb = cb; 525 553 clo->user_data = user_data; 526 554 527 xmlrpc_client_start_rpcf(&data->env, 528 data->client, 529 blog->url, (char *)"metaWeblog.getCategories", 530 _blog_metaweblog_got_categories, 531 clo, 532 (char *)"(sss)", 533 blog->id, 534 blog->user, 535 blog->pass); 536 clo->timeout_id = g_timeout_add(500, _event_loop, data); 537 } 538 539 static void _blog_metaweblog_got_recent(const char *server_url, 540 const char *method_name, 541 xmlrpc_value *param_array, 542 void *user_data, 543 xmlrpc_env *fault, 544 xmlrpc_value *retval) 555 msg = soup_xmlrpc_message_new(blog->url); 556 soup_xmlrpc_message_start_call(msg, "metaWeblog.getCategories"); 557 soup_xmlrpc_message_start_param(msg); 558 soup_xmlrpc_message_write_string(msg, blog->id); 559 soup_xmlrpc_message_end_param(msg); 560 soup_xmlrpc_message_start_param(msg); 561 soup_xmlrpc_message_write_string(msg, blog->user); 562 soup_xmlrpc_message_end_param(msg); 563 soup_xmlrpc_message_start_param(msg); 564 soup_xmlrpc_message_write_string(msg, blog->pass); 565 soup_xmlrpc_message_end_param(msg); 566 soup_xmlrpc_message_end_call(msg); 567 soup_xmlrpc_message_persist(msg); 568 569 soup_session_queue_message(data->session, SOUP_MESSAGE(msg), 570 _blog_metaweblog_got_categories, clo);
