Index: blogclient.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/blogclient/blogclient.install,v
retrieving revision 1.1
diff -u -d -b -w -r1.1 blogclient.install
--- blogclient.install	13 Jul 2006 00:55:16 -0000	1.1
+++ blogclient.install	9 Aug 2006 04:09:43 -0000
@@ -50,3 +50,8 @@
 function blogclient_update_1() {
   return _system_update_utf8(array('blogs'));
 }
\ No newline at end of file
+
+function blogclient_update_2() {
+  $ret[] = update_sql("ALTER TABLE {blogs} ADD COLUMN defaultpost tinyint(1) NOT NULL default 1");
+  return $ret;
+}
Index: blogclient.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/blogclient/blogclient.module,v
retrieving revision 1.2
diff -u -d -b -w -r1.2 blogclient.module
--- blogclient.module	13 Jul 2006 00:55:16 -0000	1.2
+++ blogclient.module	9 Aug 2006 04:09:43 -0000
@@ -5,36 +5,53 @@
 function blogclient_help($section) {
   switch ($section) {
     case 'admin/modules#description':
+    case 'admin/settings/modules#description':
       // appears on the admin module selection page
       return t('Allows users to post to blogs at the same time as thier drupal posts.');
   }
 }
 
 function blogclient_menu($may_cache) {
+  global $user;
   $items = array();
   if ($may_cache) {
     $items[] = array(
-      'path' => 'blogclient',
+      'path' => 'syndicate/blog',
       'title' => t('blog client'),
       'access' => user_access('access blogclient'),
       'callback' => 'blogclient_list',
     );
   }
   else {
-    if (arg(0) == 'blogclient') {
+    if (arg(0) == 'syndicate' && arg(1) == 'blog') {
       $items[] = array(
-        'path' => 'blogclient/edit',
-        'title' => arg(2) ? t('edit') : t('add'),
+        'path' => 'syndicate/blog/add',
+        'title' => t('add'),
+        'callback' => 'blogclient_edit',
+        'access' => user_access('admin blogclient') || (user_access('access blogclient') && (db_result(db_query('SELECT COUNT(blogid) FROM {blogs} WHERE uid = %d', $user->uid)) < 5)),
+        'type' => MENU_LOCAL_TASK,
+      );
+      if (arg(2) == 'edit' && is_numeric(arg(3))) {
+        $items[] = array(
+          'path' => 'syndicate/blog/edit',
+          'title' => t('edit'),
         'callback' => 'blogclient_edit',
         'access' => user_access('access blogclient'),
         'type' => MENU_LOCAL_TASK,
       );
+      }
       $items[] = array(
-        'path' => 'blogclient/list',
+        'path' => 'syndicate/blog/list',
         'type' => MENU_DEFAULT_LOCAL_TASK,
-        'title' => t('list'),
+        'title' => t('my blogs'),
         'weight' => -10,
       );
+      $items[] = array(
+        'path' => 'syndicate/blog/delete',
+        'type' => MENU_CALLBACK,
+        'title' => t('Delete'),
+        'callback' => 'blogclient_delete',
+      );
     }
   }
   return $items;
@@ -44,37 +61,131 @@
   return array('access blogclient', 'admin blogclient');
 }
 
+
 function blogclient_list($uid = 0) {
   global $user;
   if (!$uid) {
     $uid = $user->uid;
   }
-  $r = db_query('SELECT * FROM {blogs} WHERE uid = %d', $uid);
+  $r = db_query('SELECT title, blogid AS blogid FROM {blogs} WHERE uid = %d ORDER BY title', $uid);
+  if (!db_num_rows($r)) {
+    drupal_goto('syndicate/blog/add');
+  }
   $list = array();
   while ($blog = db_fetch_object($r)) {
-    $rows[] = array($blog->title, $blog->remote_id, l('edit', "blogclient/edit/$blog->blogid"));
+    $rows[] = array(
+      check_plain($blog->title),
+      l('edit', "syndicate/blog/edit/$blog->blogid"),
+      l('delete', "syndicate/blog/delete/$blog->blogid"),
+    );
   }
-  return theme('table', array(), $rows, array('width' => '100%'));
+  $output = theme('table', array(), $rows, array('width' => '100%'));
+  if (!user_access('admin blogclient') && db_result(db_query('SELECT COUNT(blogid) FROM {blogs} WHERE uid = %d', $user->uid)) >= 5) {
+    $output .= t('<p>Note that you have reached the maximum number of blogs allowed.</p>');
+  }
+  return $output;
 }
 
-function blogclient_edit($blogid = 0, $form_values = array()) {
+function blogclient_delete($blogid, $from_edit = 0) {
+  if (!$title = db_result(db_query('SELECT title FROM {blogs} WHERE blogid = %d', $blogid))) {
+    drupal_goto('syndicate/blog');
+  }
+  if (!isset($_POST['op']) || $_POST['op'] != t('Confirm')) {
+    $edit = $_POST['edit'];
 
-  $blogid = arg(2);
+    $form['nodes'] = array('#prefix' => '<ul>', '#suffix' => '</ul>', '#tree' => TRUE);
+    $form['nodes'][$nid] = array('#type' => 'hidden', '#value' => $nid, '#prefix' => '<li>', '#suffix' => check_plain($title) ."</li>\n");
+    $form['operation'] = array('#type' => 'hidden', '#value' => 'delete');
+
+    return confirm_form('blogclient_delete', $form,
+                        t('<p>Do you really want to delete <em>%title</em>? This action cannot be undone.</p>', array('%title' => check_plain($title))),
+                        'syndicate/blog', t('This action cannot be undone.'),
+                        t('Confirm'), t('Cancel'));
+  }
+  else {
+    drupal_set_message(t('<em>%title</em> deleted.', array('%title' => check_plain($title))));
+    db_query('DELETE FROM {blogs} WHERE blogid = %d', $blogid);
+    drupal_goto('syndicate/blog');
+  }
+}
+
+function blogclient_type_map ($type = NULL) {
+  $map = array(
+    'Blogger.com' => 'atom',
+    'Livejournal.com' => 'atom',
+    'Typepad.com' => 'atom',
+    'Wordpress.com' => 'metaweblog',
+    'Spaces.MSN.com' => 'metaweblog',
+    'atom' => 'atom',
+    'metaweblog' => 'metaweblog',
+    'blogger' => 'blogger',
+  );
+  if (!isset($type)) {
+    return $map;
+  }
+  if (isset($map[$type])) {
+    return $map[$type];
+  }
+}
+
+function blogclient_edit($blogid=0) {
   if ($blogid) {
-    $form_values = db_fetch_array(db_query('SELECT * FROM {blogs} WHERE blogid = %d', $blogid));
+    $edit = db_fetch_array(db_query('SELECT * FROM {blogs} WHERE blogid = %d', $blogid));
     if (!user_access('admin blogclient') && $edit['uid'] != $user->uid) {
-      drupal_goto('blogclient');
+      drupal_goto('syndicate/blog/add');
+    }
+    $r = db_query("SELECT blogid, defaultpost, title, endpoint, remote_id, type FROM {blogs} WHERE url = '%s'", $edit['url']);
+    while ($endpoint = db_fetch_array($r)) {
+      $endpoints[$endpoint['blogid']] = $endpoint;
+    }
+  }
+  else {
+    unset($endpoints);
+  }
+  $next  = t('Next');
+  $save  = t('Save');
+  $manual = t('Configure manually');
+  $delete = t('Delete');
+
+  if ($_POST['op']) {
+    $edit = $_POST['edit'];
+    switch($_POST['op']) {
+      case $next:
+        {
+          $edit['url'] = strtolower($edit['url']);
+          if (!valid_url($edit['url'])) {
+            form_set_error('url',t('The URL seems invalid.'));
+            break;
+          }
+          $discover = blogclient_discover($edit['url'], $edit['name'], $edit['pass']);
+          if ($discover == -401) {
+            drupal_set_message(t('Unable to log in with this username and password'));
+            if (strpos($edit['url'], 'spaces.msn.com') !== FALSE) {
+              drupal_set_message(t('For MSN Spaces, you need to enable Email publishing and use the name of your Space for username and the secret word from Email publishing as password.'));
+            }
+          }
+          elseif ($endpoints = $discover) {
+            if (count($endpoints) > 1) {
+              drupal_set_message(t('Your blogs have been found and we are ready to post to it.'));
+            }
+            else {
+              drupal_set_message(t('Your blog has been found and we are ready to post to it.'));
+            }
+          }
+          else {
+            drupal_set_message(t('We were unable to configure the system to be able to post to your blog. Try configuring manually.'));
+          }
+          break;
+        }
+      case $manual:
+        $endpoints = ''; // set endpoints to something empty
+        break;
+      case $delete:
+        drupal_goto("syndicate/blog/delete/$blogid/1");
+        break;
     }
   }
   $form_values = array_merge($form_values,$_POST['edit']);
-  $form['title'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Name'),
-    '#default_value' => $form_values['title'],
-    '#size' => 40,
-    '#maxlength' => 255,
-    '#description' => t('Name of this blog'),
-  );
   $form['url'] = array(
     '#type' => 'textfield',
     '#title' => t('URL'),
@@ -89,86 +200,157 @@
     '#default_value' => $form_values['name'],
     '#size' => 15,
     '#maxlength' => 64,
-  );$form['pass'] = array(
+  );
+  $form['pass'] = array(
     '#type' => 'password',
     '#title' => t('Password'),
     '#default_value' => $form_values['pass'],
     '#size' => 15,
     '#maxlength' => 64,
   );
-  $form['endpoint'] = array(
+
+  if (!isset($endpoints) && !$form_values['stage2']) {
+    $form['next'] = array(
+      '#type' => 'button',
+      '#value' => $next,
+    );
+    $form['save'] = array(
+      '#type' => 'submit',
+      '#value' => $manual,
+    );
+  }
+  else {
+    $rows = array();
+    $options = drupal_map_assoc(array_keys(blogclient_type_map()));
+    $form['stage2'] = array('#type' => 'hidden','#value' => '1');
+    if (empty($endpoints)) {
+      $endpoints = array(array());
+    }
+    $value = implode('|', array_keys($endpoints));
+    $form['endpoints'] = array('#type'=>'hidden', '#value'=>$value);
+
+    foreach ($endpoints as $current_blogid => $endpoint) {
+      $form['defaultpost']['defaultpost'. $current_blogid] = array(
+        '#type' => 'checkbox',
+        '#title' => '',
+        '#return_value' => 1,
+        '#default_value' => $blogid ? $endpoint['defaultpost'] : 1,
+      );
+      $form['title']['title'. $current_blogid] = array(
     '#type' => 'textfield',
-    '#title' => t('Endpoint'),
-    '#default_value' => $form_values['endpoint'],
-    '#size' => 40,
+        '#title' => '',
+        '#default_value' => $endpoint['title'],
+        '#size' => 30,
     '#maxlength' => 255,
-    '#description' => t('The endpoint we should post to, for example   https://www.blogger.com/atom/1234567890. Try pressing autodiscover below if you do not know the value of this.'),
   );
-  $form['remote_id'] = array(
+      $form['endpoint']['endpoint'. $current_blogid] = array(
     '#type' => 'textfield',
-    '#title' => t('Remote id'),
-    '#default_value' => $form_values['remote_id'],
-    '#size' => 15,
-    '#maxlength' => 64,
+        '#title' => '',
+        '#default_value' => $endpoint['endpoint'],
+        '#size' => 20,
+        '#maxlength' => 255,
   );
-  $form['type'] = array(
+      if ($endpoint['type'] == 'atom') {
+        $form['remote_id']['remote_id'. $current_blogid] = array(
+          '#type' => 'hidden',
+          '#value' => '',
+        );
+      }
+      else {
+        $form['remote_id']['remote_id'. $current_blogid] = array(
+          '#type' => 'textfield',
+          '#size' => 10,
+          '#maxsize' => 30,
+          '#default_value' => $endpoint['remote_id'],
+        );
+      }
+      $form['type']['type'. $current_blogid] = array(
     '#type' => 'select',
-    '#title' => t('Type'),
-    '#default_value' => $form_values['type'],
-    '#options' => drupal_map_assoc(array('atom', 'metaweblog', 'blogger')),
+        '#title' => '',
+        '#default_value' => $endpoint['type'],
+        '#options' => $options,
   );
-  $form['save'] = array(
-    '#type' => 'submit',
-    '#value' => t('Save'),
+      $form['save']['save'. $current_blogid] = array(
+        '#type' => 'checkbox',
+        '#title' => '',
+        '#return_value' => 1,
+        '#default_value' => 1,
   );
-  $form['autodiscover'] = array(
-    '#type' => 'button',
-    '#value' => t('Autodiscover'),
+    }
+
+    $form['next'] = array(
+      '#type' => 'submit',
+      '#value' => $save,
   );
+
         if ($blogid) {
-    $form['blogid'] = array(
-      '#type' => 'hidden',
-      '#value' => $blogid,
+      $form['delete'] = array(
+        '#type' => 'submit',
+        '#value' => $delete,
     );
         }
 
-  if ($_POST['op'] == t('Autodiscover')) {
-    $endpoint = blogclient_discover($form_values['url'], $form_values['name'], $form_values['pass']);
-    $form['endpoint']['#value'] = $endpoint['endpoint'];
-    $form['type']['#value'] = $endpoint['type'];
-    $form['remote_id']['#value'] = $endpoint['remote_id'];
+    return drupal_get_form('blogclient_autodiscover', $form);
+  }
 
-    if (!$form_values['title']) {
-      $form['title']['#value'] = $endpoint['title'];
+  return drupal_get_form('blogclient_edit', $form);
         }
+
+function theme_blogclient_autodiscover($form) {
+  foreach (explode('|', $form['endpoints']['#value']) as $current_blogid) {
+    $row = array();
+    foreach (array('defaultpost','title','endpoint','remote_id','type','save') as $key) {
+      $row[] = form_render($form[$key][$key.$current_blogid]);
     }
-  return drupal_get_form('blogclient_edit', $form);
+    $rows[] = $row;
   }
 
+  $buttons = '';
+  foreach (array('next','delete') as $button) {
+    if ($form[$button]) {
+      $buttons .= form_render($form[$button]);
+    }
+  }
+  $output  = '';
+  $output .= form_render($form);
+  $output .= $buttons;
+  $output .= theme('table', array(t('Default'), t('Name'), t('API URL'), $endpoint['type'] == 'atom' ? '&nbsp;' : t('Remote id'), t('Type'), t('Save?')), $rows);
+  return $output;
+}
 
-function blogclient_edit_submit($form_id, $form_values) {
+function blogclient_autodiscover_submit($form_id, $form_values) {
    global $user;
-   if ($form_values['blogid']) {
-     db_query("UPDATE {blogs} SET url = '%s', name = '%s', pass = '%s', remote_id = '%s', type = '%s', title = '%s', endpoint = '%s' WHERE blogid = %d", $form_values['url'], $form_values['name'], $form_values['pass'], $form_values['remote_id'], $form_values['type'], $form_values['title'], $form_values['endpoint'], $form_values['blogid']);
+   $blogid = arg(3);
+   if ($blogid) {
+     foreach (explode('|', $form_values['endpoints']) as $current_blogid) {
+       db_query("UPDATE {blogs} SET url = '%s', name = '%s', pass = '%s', remote_id = '%s', type = '%s', title = '%s', endpoint = '%s', defaultpost = %d WHERE blogid = %d",
+         $form_values['url'], $form_values['name'], $form_values['pass'], $form_values['remote_id'.$current_blogid], $form_values['type'.$current_blogid],  $form_values['title'.$current_blogid], $form_values['endpoint'.$current_blogid], $form_values['defaultpost'.$current_blogid], $current_blogid);
+     }
    }
    else {
+     foreach (explode('|', $form_values['endpoints']) as $current_blogid) {
      $blogid = db_next_id('{blogs}_blogid');
-     db_query("INSERT INTO {blogs} (blogid, url, name, pass, remote_id, type, uid, title, endpoint) VALUES (%d, '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s')", $blogid, $form_values['url'], $form_values['name'], $form_values['pass'], $form_values['remote_id'], $form_values['type'], $user->uid, $form_values['title'], $form_values['endpoint']);
+       db_query("INSERT INTO {blogs} (blogid, url, name, pass, remote_id, type, uid, title, endpoint, defaultpost) VALUES (%d, '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', %d)", 
+         $blogid, $form_values['url'], $form_values['name'], $form_values['pass'], $form_values['remote_id'.$current_blogid], $form_values['type'.$current_blogid], $user->uid, $form_values['title'.$current_blogid], $form_values['endpoint'.$current_blogid], $form_values['defaultpost'.$current_blogid]);
 }
-   return 'blogclient';
+   }
+   return 'syndicate/blog';
 }
 
 
 function _blogclient_discover($url, $name, $pass) {
   $data = _blogclient_discover_curl($url, $name, $pass);
-  $links = preg_match_all('/<link.*>/U', $data, $m);
+  if ($data == -401) {
+    return -401;
+  }
+  preg_match_all('/<link .*>/U', $data, $m);
   $atom_feed_count = 0;
   $atom_post_links = array();
   $blogapi_links = array();
   foreach ($m[0] as $link) {
     $processed_link = _blogclient_discover_process($link);
     if ($processed_link['type'] == 'application/rsd+xml') {
-      $blogapi_links = _blogclient_discover_rsd($processed_link['href']);
+      $blogapi_links = _blogclient_discover_rsd($processed_link['href'], $name, $pass);
     }
     if ($processed_link['type'] == 'application/atom+xml') {
       if ($processed_link['rel'] == 'service.post') {
@@ -183,22 +365,38 @@
   if ($n > 1 && $n != $atom_feed_count) { // this is for blogger.com
     $false_atom_post_links = $atom_post_links;
     $atom_post_links = array();
+    $failed_counter = 0;
     foreach ($false_atom_post_links as $blog) {
       $return = _blogclient_discover($blog['endpoint'], $name, $pass);
-      $atom_post_links = array_merge($atom_post_links, $return['atom_post_links']);
+      if ($return == -401) {
+        $failed_counter++;
     }
+      else {
+        $atom_post_links = array_merge($atom_post_links, $return['atom']);
   }
-  return array('blogapi_links' => $blogapi_links, 'atom_post_links' => $atom_post_links);
+    }
+    if ($failed_counter == count($false_atom_post_links)) {
+      return -401;
+    }
+  }
+  $return = array();
+  if (!empty($atom_post_links)) {
+    $return['atom'] = $atom_post_links;
+  }
+  return array_merge($return, $blogapi_links);
 }
 
 function blogclient_discover($url, $name, $pass) {
   $links = _blogclient_discover($url, $name, $pass);
-  $endpoints = array_merge($links['blogapi_links'], $links['atom_post_links']);
-  foreach (array('atom', 'metaweblog', 'blogger') as $type) {
-    foreach ($endpoints as $endpoint) {
-      if ($endpoint['type'] == $type) {
-        return $endpoint;
+  if ($blogs = blogclient_discover_blogs($links, $name, $pass)) {
+    $links = $blogs;
       }
+  if ($links == -401) {
+    return -401;
+  }
+  foreach (array('atom', 'metaweblog', 'blogger') as $type) {
+    if (isset($links[$type])) {
+      return $links[$type];
     }
   }
 }
@@ -206,60 +404,109 @@
 function _blogclient_discover_curl($url, $name = '', $pass = '') {
   $ch = curl_init();
   curl_setopt($ch, CURLOPT_URL, $url);
-  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+  curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
   curl_setopt($ch, CURLOPT_TIMEOUT, 4);
-  if ($name) {
-    curl_setopt($ch, CURLOPT_USERPWD, $name .':'. $pass);
-  }
   curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
   curl_setopt($ch, CURLOPT_MAXREDIRS, 2);
+  curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)');
+  if ($name) {
+    if ($url[4] == 's') {
+      curl_setopt($ch, CURLOPT_USERPWD, "$name:$pass");
+    }
+    else {
+      curl_setopt($ch, CURLOPT_HTTPHEADER, blogclient_wsse_headers($name, $pass));
+    }
+  }
   $data = curl_exec($ch);
   if (curl_errno($ch)) {
     return FALSE;
   }
+  $return_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+  if ($return_code == 401) {
+    return -401;
+  }
+  curl_close($ch);
   return $data;
 }
 
 function _blogclient_discover_process($tag) {
   $processed_tag = array();
-  preg_match_all('/ ([^=]+)=([\'"])([^\'"]+)\2/', $tag, $m, PREG_SET_ORDER);
+  preg_match_all('/ ([^=]+)="([^"]+)"/', $tag, $m, PREG_SET_ORDER);
   foreach ($m as $attr) {
-    $processed_tag[$attr[1]] = $attr[3];
+    $processed_tag[$attr[1]] = $attr[2];
   }
   return $processed_tag;
 }
 
 
-function _blogclient_discover_rsd($url) {
+function _blogclient_discover_rsd($url, $name, $pass) {
   $data = _blogclient_discover_curl($url);
   preg_match('|<homePageLink>(.*)</homePageLink>|', $data, $m);
   $title = $m[1];
-  $api = preg_match_all('/<api .*>/U', $data, $m);
+  preg_match_all('/<api .*>/U', $data, $m);
   $endpoints = array();
   $possible_apis = array('blogger', 'metaweblog');
   foreach ($m[0] as $api) {
     $processed_api = _blogclient_discover_process($api);
     $possible_api = strtolower($processed_api['name']);
     if (isset($possible_apis)) {
-      $endpoints[] = array('endpoint' => $processed_api['apiLink'], 'type' => $possible_api, 'remote_id' => $processed_api['blogID'], 'title' => $title);
+      $endpoints[$possible_api][] = array('endpoint' => $processed_api['apiLink'], 'type' => $possible_api, 'remote_id' => $processed_api['blogID'], 'title' => $title);
     }
   }
   return $endpoints;
-//<api name="Blogger" preferred="true" apiLink="http://www.blogger.com/api" blogID="30787618" />
+}
+
+function blogclient_discover_blogs($links, $name, $pass) {
+  $blogs = array();
+  foreach (array('atom', 'metaweblog', 'blogger') as $type) {
+    if (isset($links[$type])) {
+      if ($type == 'atom') {
+        foreach ($links['atom'] as $endpoint) {
+          // remove last part of URL
+          $data = _blogclient_discover_curl(preg_replace('!/[^/]+/?$!', '', $endpoint['endpoint']), $name, $pass);
+          if ($data == -401) {
+            return -401;
+          }
+          if (preg_match_all('/<link.*>/U', $data, $m)) {
+            $atom_post_links = array();
+            foreach ($m[0] as $link) {
+              $processed_link = _blogclient_discover_process($link);
+              if ($processed_link['type'] == 'application/atom+xml' && $processed_link['rel'] == 'service.post') {
+                $blogs['atom'][] = array('endpoint' => $processed_link['href'], 'type' => 'atom', 'remote_id' => '', 'title' => $processed_link['title']);
+              }
+            }
+          }
+        }
+      }
+      else {
+        foreach ($links[$type] as $endpoint) {
+          $result = xmlrpc($endpoint['endpoint'], 'blogger.getUsersBlogs', '0123456789ABCDEF', $name, $pass);
+          if (is_array($result)) {
+            foreach ($result as $blog) {
+              $type = $endpoint['type'];
+              $blogs[$type][] = array('endpoint' => $endpoint['endpoint'], 'type' => $type, 'remote_id' => $blog['blogid'], 'title' => $blog['blogName']);
+            }
+          }
+          elseif (xmlrpc_errno() == 3001 || strpos(strtolower(xmlrpc_error_msg()), 'password') !== FALSE) {
+            return -401;
+          }
+        }
+      }
+    }
+  }
+  return $blogs;
 }
 
 function blogclient_nodeapi($node, $op) {
   global $user;
   switch ($op) {
     case 'insert':
-    case 'update':
       foreach ($node->blogs as $blogid) {
-        $ret = blogclient_post_node($node->nid, $blogid);
-        if ($ret !== TRUE) {
-          drupal_set_message(t('blogclient: %errormessage', array('%errormessage'=>$ret)), 'error');
-        }
+        blogclient_post_node($node->nid, $blogid);
       }
       break;
+    /* FIXME - keep track of any posted ID and do an updated on update */
+    // case 'update':
   }
 }
 
@@ -285,20 +532,17 @@
   global $user;
   $node = node_load(array('nid' => $nid));
   $blog = db_fetch_object(db_query('SELECT * FROM {blogs} WHERE blogid = %d AND uid = %d', $blogid, $user->uid)); // uid only for safety
-  $function = '_blogclient_'. $blog->type .'_post_node';
+  $function = '_blogclient_'. blogclient_type_map($blog->type) .'_post_node';
   if (function_exists($function)) {
     return $function($node, $blog);
   }
 }
 
 function _blogclient_atom_post_node($node, $blog) {
-  $headers = array("Content-type: application/atom+xml");
   $issued = gmdate("Y-m-d\TH:i:s\Z", time());
   $title = $node->title;
-  $body = $node->body ? $node->body : $node->details;
-  $body = str_replace(array('[q]', '[/q]'), '', $body);
   $blog_id = $blog->remote_id;
-  /* FIXME */
+  $body = $node->body;
   $generator_url = 'http://nowpublic.com';
   $generator = 'NowPublic.com';
 
@@ -313,26 +557,55 @@
 </content>
 </entry>
 CONTENT;
-  // Use curl to post to your blog.
   $ch = curl_init();
+  if ($blog->endpoint[4] == 's') {
+    curl_setopt($ch, CURLOPT_USERPWD, "$blog->name:$blog->pass");
+    $headers = array();
+  }
+  else {
+    $headers =  blogclient_wsse_headers($blog->name, $blog->pass);
+  }
+  $headers[] = "Content-type: application/atom+xml";
   curl_setopt($ch, CURLOPT_URL, $blog->endpoint); // "https://www.blogger.com/atom/". $blog_id
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
   curl_setopt($ch, CURLOPT_TIMEOUT, 4);
   curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
-  curl_setopt($ch, CURLOPT_USERPWD, $blog->name .':'. $blog->pass);
   curl_setopt($ch, CURLOPT_POSTFIELDS, $content);
   $data = curl_exec($ch);
   $result = curl_errno($ch) ? curl_error($ch) : TRUE;
+  watchdog('blogclient', t("Posted to %endpoint, result is %result", array('%endpoint' => $blog->endpoint, '%result' => check_plain($data))));
   return $result;
 }
 
 function _blogclient_blogger_post_node($node, $blog) {
-  $body = $node->body ? $node->body : $node->details;
-  xmlrpc($blog->endpoint, 'blogger.newPost', '0123456789ABCDEF', $blog->remote_id, $blog->name, $blog->pass, "<title>$node->title</title>$body", TRUE);
-  return xmlrpc_errno() ? xmlrpc_error_msg() : TRUE;
+  $result = xmlrpc($blog->endpoint, 'blogger.newPost', '0123456789ABCDEF', $blog->remote_id, $blog->name, $blog->pass, $node->body, TRUE);
+  watchdog('blogclient', t("Posted to %endpoint, result is %result, error is %error", array('%endpoint' => $blog->endpoint, '%result' => check_plain($result), 'error' => xmlrpc_error_msg())));
 }
+
 function _blogclient_metaweblog_post_node($node, $blog) {
-  $body = $node->body ? $node->body : $node->details;
-  xmlrpc($blog->endpoint, 'metaWeblog.newPost',  $blog->remote_id, $blog->name, $blog->pass, array('title' => $node->title, 'description' => $body), TRUE);
-  return xmlrpc_errno() ? xmlrpc_error_msg() : TRUE;
+  $result = xmlrpc($blog->endpoint, 'metaWeblog.newPost',  $blog->remote_id, $blog->name, $blog->pass, array('title' => $node->title, 'description' => $node->body), TRUE);
+  watchdog('blogclient', t("Posted to %endpoint, result is %result, error is %error", array('%endpoint' => $blog->endpoint, '%result' => check_plain($result), '%error' => xmlrpc_error_msg())));
+}
+
+function blogclient_wsse_headers($name, $pass) {
+  $timestamp = gmdate('Y-m-d\TH:i:s\Z');
+  $nonce = md5(microtime());
+  $digest = base64_encode(pack("H*", sha1($nonce . $timestamp . $pass)));
+  $wsse_array = array(
+    'Username' => $name,
+    'PasswordDigest' => $digest,
+    'Nonce' => base64_encode($nonce),
+    'Created' => $timestamp,
+  );
+  $wsse = 'X-WSSE: UsernameToken ';
+  foreach ($wsse_array as $k => $v) {
+    $wsse .= $k .'="'. $v .'"';
+    if ($k != 'Created') {
+      $wsse .= ', ';
+    }
+  }
+  return array(
+    'Authorization: WSSE profile="UsernameToken"',
+    $wsse
+  );
 }
