fixed some clang warnings
[k8lowj.git] / src / livejournal.c
blob1dc21cd9eef636f73caec22b99b74923b247b3fa
1 /* logjam - a GTK client for LiveJournal.
2 * Copyright (C) 2003 Evan Martin <evan@livejournal.com>
3 */
4 #include "glib-all.h"
6 #include <string.h>
8 #include "liblj/editpostevent.h"
10 #include "account.h"
11 #include "conf_xml.h"
12 #include "jamdoc.h"
13 #include "jam_xml.h"
14 #include "network.h"
15 #include "util.h"
18 struct _JamHostLJ {
19 JamHost host;
20 LJServer *server;
24 JamAccount *jam_account_lj_new (LJServer *server, const char *username) {
25 JamAccountLJ *acc = JAM_ACCOUNT_LJ(g_object_new(jam_account_lj_get_type(), NULL));
26 acc->user = lj_user_new(server);
27 if (username) acc->user->username = g_strdup(username);
28 return JAM_ACCOUNT(acc);
32 static GSList *parsepickws (xmlDocPtr doc, xmlNodePtr node) {
33 GSList *pickws = NULL;
34 for (node = node->xmlChildrenNode; node != NULL; node = node->next) {
35 XML_GET_LIST("pickw", pickws, jam_xmlGetString)
36 XML_GET_END("parsepickws")
38 return pickws;
42 static GSList *parseusejournals (xmlDocPtr doc, xmlNodePtr node) {
43 GSList *l = NULL;
44 for (node = node->xmlChildrenNode; node != NULL; node = node->next) {
45 if (xmlStrcmp(node->name, BAD_CAST "usejournal") == 0) {
46 char *journal = jam_xmlGetString(doc, node);
47 l = g_slist_append(l, journal);
48 } else {
49 XML_GET_END("usejournals")
52 return l;
56 static GSList *parsefriendgroups (xmlDocPtr doc, xmlNodePtr node) {
57 GSList *fgs = NULL;
58 for (node = node->xmlChildrenNode; node != NULL; node = node->next) {
59 if (xmlStrcmp(node->name, BAD_CAST "friendgroup") == 0) {
60 int id;
61 if (jam_xmlGetIntProp(node, "id", &id)) {
62 LJFriendGroup *fg = lj_friendgroup_new();
63 fg->id = id;
64 fg->name = jam_xmlGetString(doc, node);
65 jam_xmlGetIntProp(node, "ispublic", &fg->ispublic);
66 fgs = g_slist_append(fgs, fg);
68 } else {
69 XML_GET_END("parsefriendgroups")
72 return fgs;
76 static GSList *parsewebmenu (xmlDocPtr doc, xmlNodePtr node) {
77 GSList *webmenu = NULL;
78 LJWebMenuItem *wmi;
79 xmlChar *text, *url;
80 for (node = node->xmlChildrenNode; node != NULL; node = node->next) {
81 if (xmlStrcmp(node->name, BAD_CAST "menuitem") == 0) {
82 wmi = lj_webmenuitem_new();
83 if ((text = xmlGetProp(node, BAD_CAST "text"))) {
84 wmi->text = g_strdup((char *)text);
85 if ((url = xmlGetProp(node, BAD_CAST "url"))) {
86 wmi->url = g_strdup((char *)url);
87 xmlFree(url);
89 xmlFree(text);
91 if (node->xmlChildrenNode) wmi->subitems = parsewebmenu(doc, node);
92 webmenu = g_slist_append(webmenu, wmi);
93 } else {
94 XML_GET_END("parsewebmenu")
97 return webmenu;
101 static void writewebmenu (xmlNodePtr parent, GSList *webmenu) {
102 GSList *l;
103 xmlNodePtr node;
104 LJWebMenuItem *wmi;
105 for (l = webmenu; l != NULL; l = l->next) {
106 wmi = (LJWebMenuItem *) l->data;
107 node = xmlNewChild(parent, NULL, BAD_CAST "menuitem", NULL);
108 if (wmi->text) xmlSetProp(node, BAD_CAST "text", BAD_CAST wmi->text);
109 if (wmi->url) xmlSetProp(node, BAD_CAST "url", BAD_CAST wmi->url);
110 if (wmi->subitems) writewebmenu(node, wmi->subitems);
115 void jam_account_lj_write (JamAccountLJ *account, xmlNodePtr node) {
116 LJUser *user = account->user;
117 xmlNodePtr xmlList, child;
118 GSList *l;
119 char buf[10];
120 LJFriendGroup *fg;
122 if (user->fullname) xmlNewTextChild(node, NULL, BAD_CAST "fullname", BAD_CAST user->fullname);
123 if (account->lastupdate) jam_xmlAddInt(node, "lastupdate", (int)account->lastupdate);
124 if (user->checkfriends) jam_xmlAddInt(node, "checkfriends", (int)TRUE);
125 if (account->cfmask) {
126 g_snprintf(buf, 10, "%d", account->cfmask);
127 xmlNewTextChild(node, NULL, BAD_CAST "cfmask", BAD_CAST buf);
129 if (user->pickws) {
130 xmlList = xmlNewChild(node, NULL, BAD_CAST "pickws", NULL);
131 for (l = user->pickws; l != NULL; l = l->next) {
132 xmlNewTextChild(xmlList, NULL, BAD_CAST "pickw", BAD_CAST l->data);
135 if (user->usejournals) {
136 xmlList = xmlNewChild(node, NULL, BAD_CAST "usejournals", NULL);
137 for (l = user->usejournals; l != NULL; l = l->next) {
138 xmlNewTextChild(xmlList, NULL, BAD_CAST "usejournal", BAD_CAST l->data);
141 if (user->friendgroups) {
142 xmlList = xmlNewChild(node, NULL, BAD_CAST "friendgroups", NULL);
143 for (l = user->friendgroups; l != NULL; l = l->next) {
144 fg = (LJFriendGroup *) l->data;
145 child = xmlNewTextChild(xmlList, NULL, BAD_CAST "friendgroup", BAD_CAST fg->name);
146 g_snprintf(buf, 10, "%d", fg->id);
147 xmlSetProp(child, BAD_CAST "id", BAD_CAST buf);
148 g_snprintf(buf, 10, "%d", fg->ispublic);
149 xmlSetProp(child, BAD_CAST "ispublic", BAD_CAST buf);
152 if (user->webmenu) {
153 xmlList = xmlNewChild(node, NULL, BAD_CAST "webmenu", NULL);
154 writewebmenu(xmlList, user->webmenu);
159 JamAccount *jam_account_lj_from_xml (xmlDocPtr doc, xmlNodePtr node, JamHostLJ *host) {
160 JamAccount *account;
161 JamAccountLJ *accountlj;
162 LJUser *user;
163 guint32 lastupdate = 0;
164 account = jam_account_lj_new(jam_host_lj_get_server(host), NULL);
165 accountlj = JAM_ACCOUNT_LJ(account);
166 user = accountlj->user;
167 for (node = node->xmlChildrenNode; node != NULL; node = node->next) {
168 XML_GET_STR("username", user->username)
169 XML_GET_STR("fullname", user->fullname)
170 XML_GET_STR("password", user->password)
171 XML_GET_BOOL("checkfriends", user->checkfriends)
172 XML_GET_UINT32("lastupdate", lastupdate)
173 XML_GET_FUNC("pickws", user->pickws, parsepickws)
174 XML_GET_FUNC("usejournals", user->usejournals, parseusejournals)
175 XML_GET_FUNC("friendgroups", user->friendgroups, parsefriendgroups)
176 XML_GET_FUNC("webmenu", user->webmenu, parsewebmenu)
177 XML_GET_UINT32("cfmask", accountlj->cfmask)
178 XML_GET_END("jam_account_lj_from_xml")
180 accountlj->lastupdate = (time_t)lastupdate;
181 return account;
185 const gchar *jam_account_lj_get_username (JamAccount *acc) {
186 return JAM_ACCOUNT_LJ(acc)->user->username;
190 const gchar *jam_account_lj_get_password (JamAccount *acc) {
191 return JAM_ACCOUNT_LJ(acc)->user->password;
195 gboolean jam_account_lj_get_checkfriends (JamAccount *acc) {
196 return JAM_ACCOUNT_LJ(acc)->user->checkfriends;
200 static void jam_account_lj_set_password (JamAccount *acc, const char *password) {
201 string_replace(&JAM_ACCOUNT_LJ(acc)->user->password, g_strdup(password));
205 LJUser *jam_account_lj_get_user (JamAccountLJ *acc) {
206 return acc->user;
210 LJServer *jam_account_lj_get_server (JamAccountLJ *acc) {
211 return acc->user->server;
215 guint32 jam_account_lj_get_cfmask (JamAccountLJ *acc) {
216 return acc->cfmask;
220 void jam_account_lj_set_cfmask (JamAccountLJ *acc, guint32 mask) {
221 acc->cfmask = mask;
225 static void jam_account_lj_class_init (JamAccountClass *klass) {
226 klass->get_username = jam_account_lj_get_username;
227 klass->set_password = jam_account_lj_set_password;
228 klass->get_password = jam_account_lj_get_password;
232 GType jam_account_lj_get_type (void) {
233 static GType new_type = 0;
234 if (!new_type) {
235 const GTypeInfo new_info = {
236 sizeof(JamAccountClass),
237 NULL,
238 NULL,
239 (GClassInitFunc) jam_account_lj_class_init,
240 NULL,
241 NULL,
242 sizeof(JamAccountLJ),
244 NULL
246 new_type = g_type_register_static(JAM_TYPE_ACCOUNT, "JamAccountLJ", &new_info, 0);
248 return new_type;
252 LJServer *jam_host_lj_get_server (JamHostLJ *host) {
253 return host->server;
257 static const char *jam_host_lj_get_stock_icon (void) {
258 return "logjam-server";
262 static GSList *parsemoods (xmlDocPtr doc, xmlNodePtr node) {
263 GSList *moods = NULL;
264 LJMood *mood;
265 for (node = node->xmlChildrenNode; node != NULL; node = node->next) {
266 if (xmlStrcmp(node->name, BAD_CAST "mood") == 0) {
267 xmlChar *idstr;
268 char *name;
269 idstr = xmlGetProp(node, BAD_CAST "id");
270 name = jam_xmlGetString(doc, node);
271 /* an older bug causes some bad moods to be stored. filter them out. */
272 if (idstr == NULL || name == NULL) {
273 if (idstr) xmlFree(idstr);
274 if (name) xmlFree(name);
275 continue;
277 mood = g_new0(LJMood, 1);
278 mood->id = atoi((char *)idstr);
279 xmlFree(idstr);
280 mood->name = name;
281 idstr = xmlGetProp(node, BAD_CAST "parentid");
282 if (idstr) {
283 mood->parentid = atoi((char *)idstr);
284 xmlFree(idstr);
286 moods = g_slist_append(moods, mood);
287 } else {
288 XML_GET_END("parsemoods")
291 return moods;
295 static gboolean jam_host_lj_load_xml (JamHost *host, xmlDocPtr doc, xmlNodePtr node) {
296 LJServer *server = JAM_HOST_LJ(host)->server;
297 XML_GET_STR("url", server->url)
298 XML_GET_INT("protocolversion", server->protocolversion)
299 XML_GET_FUNC("moods", server->moods, parsemoods)
300 /* else: */ return FALSE;
301 return TRUE;
305 static void jam_host_lj_save_xml (JamHost *host, xmlNodePtr servernode) {
306 JamHostLJ *hostlj = JAM_HOST_LJ(host);
307 xmlNodePtr node;
308 GSList *l;
309 LJServer *server = hostlj->server;
310 xmlSetProp(servernode, BAD_CAST "protocol", BAD_CAST "livejournal");
311 xmlNewTextChild(servernode, NULL, BAD_CAST "url", BAD_CAST server->url);
312 jam_xmlAddInt(servernode, "protocolversion", server->protocolversion);
313 node = xmlNewChild(servernode, NULL, BAD_CAST "moods", NULL);
314 for (l = server->moods; l != NULL; l = l->next) {
315 LJMood *mood = (LJMood *) l->data;
316 char buf[10];
317 xmlNodePtr moodnode = xmlNewTextChild(node, NULL, BAD_CAST "mood", BAD_CAST mood->name);
318 g_snprintf(buf, 10, "%d", mood->id);
319 xmlSetProp(moodnode, BAD_CAST "id", BAD_CAST buf);
320 if (mood->parentid) {
321 g_snprintf(buf, 10, "%d", mood->parentid);
322 xmlSetProp(moodnode, BAD_CAST "parentid", BAD_CAST buf);
328 static JamAccount *jam_host_lj_make_account (JamHost *host, const char *username) {
329 JamAccount *acc;
330 acc = jam_account_lj_new(JAM_HOST_LJ(host)->server, username);
331 jam_host_add_account(host, acc);
332 return acc;
336 static gboolean jam_host_lj_do_action (JamHost *host, NetContext *ctx, JamDoc *doc, gboolean edit, gboolean delete, GError **err) {
337 LJEditPostEvent *editpostevent;
338 JamAccount *account = jam_doc_get_account(doc);
339 JamAccountLJ *acc = JAM_ACCOUNT_LJ(account);
340 LJEntry *entry;
341 gboolean ret = FALSE;
342 entry = jam_doc_get_entry(doc);
343 if (!edit)
344 entry->itemid = 0;
345 else if (delete) {
346 g_free(entry->event);
347 entry->event = NULL;
349 editpostevent = lj_editpostevent_new(jam_account_lj_get_user(acc), jam_doc_get_usejournal(doc), edit, entry);
350 if (net_run_verb_ctx((LJVerb *)editpostevent, ctx, err)) ret = TRUE;
351 /*fprintf(stderr, "url: [%s]\n", lj_result_get(((LJVerb *)editpostevent)->result, "url")); */
352 jam_doc_set_url(doc, lj_result_get(((LJVerb *) editpostevent)->result, "url"));
353 lj_editpostevent_free(editpostevent);
354 lj_entry_free(entry);
355 return ret;
359 static gboolean jam_host_lj_do_post (JamHost *host, NetContext *ctx, void *doc, GError **err) {
360 return jam_host_lj_do_action(host, ctx, doc, FALSE, FALSE, err);
364 static gboolean jam_host_lj_do_edit (JamHost *host, NetContext *ctx, void *doc, GError **err) {
365 return jam_host_lj_do_action(host, ctx, doc, TRUE, FALSE, err);
369 static gboolean jam_host_lj_do_delete (JamHost *host, NetContext *ctx, void *doc, GError **err) {
370 return jam_host_lj_do_action(host, ctx, doc, TRUE, TRUE, err);
374 static void jam_host_lj_class_init (JamHostClass *klass) {
375 klass->get_stock_icon = jam_host_lj_get_stock_icon;
376 klass->save_xml = jam_host_lj_save_xml;
377 klass->load_xml = jam_host_lj_load_xml;
378 klass->make_account = jam_host_lj_make_account;
379 klass->do_post = jam_host_lj_do_post;
380 klass->do_edit = jam_host_lj_do_edit;
381 klass->do_delete = jam_host_lj_do_delete;
385 GType jam_host_lj_get_type (void) {
386 static GType new_type = 0;
387 if (!new_type) {
388 const GTypeInfo new_info = {
389 sizeof(JamHostClass),
390 NULL,
391 NULL,
392 (GClassInitFunc) jam_host_lj_class_init,
393 NULL,
394 NULL,
395 sizeof(JamHostLJ),
397 NULL
399 new_type = g_type_register_static(JAM_TYPE_HOST, "JamHostLJ", &new_info, 0);
401 return new_type;
405 JamHostLJ *jam_host_lj_new (LJServer *s) {
406 JamHostLJ *h = JAM_HOST_LJ(g_object_new(jam_host_lj_get_type(), NULL));
407 h->server = s;
408 return h;