diff --git a/plugins/Bookmark/deliciousbackupimporter.php b/plugins/Bookmark/deliciousbackupimporter.php index b9dc7d8879..6ab87b5212 100644 --- a/plugins/Bookmark/deliciousbackupimporter.php +++ b/plugins/Bookmark/deliciousbackupimporter.php @@ -1,123 +1,216 @@ . + * + * @category Bookmark + * @package StatusNet + * @author Evan Prodromou + * @copyright 2010 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +require_once INSTALLDIR . '/lib/apiauth.php'; + +/** + * Importer class for Delicious bookmarks + * + * @category Bookmark + * @package StatusNet + * @author Evan Prodromou + * @copyright 2010 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ class DeliciousBackupImporter { - function importBookmarks($user, $body) - { - $doc = $this->importHTML($body); + /** + * Import an in-memory bookmark list to a user's account + * + * Take a delicious.com backup file (same as Netscape bookmarks.html) + * and import to StatusNet as Bookmark activities. + * + * The document format is terrible. It consists of a
with + * a bunch of
's, occasionally with
's. + * There are sometimes

's lost inside. + * + * @param User $user User whose feed we're going to fill + * @param string $body Body of the file + * + * @return void + */ - $dls = $doc->getElementsByTagName('dl'); + function importBookmarks($user, $body) + { + $doc = $this->importHTML($body); - if ($dls->length != 1) { - throw new ClientException(_("Bad import file.")); - } + $dls = $doc->getElementsByTagName('dl'); - $dl = $dls->item(0); + if ($dls->length != 1) { + throw new ClientException(_("Bad import file.")); + } - $children = $dl->childNodes; + $dl = $dls->item(0); - $dt = null; + $children = $dl->childNodes; - for ($i = 0; $i < $children->length; $i++) { - try { - $child = $children->item($i); - if ($child->nodeType != XML_ELEMENT_NODE) { - continue; - } - common_log(LOG_INFO, $child->tagName); - switch (strtolower($child->tagName)) { - case 'dt': - if (!empty($dt)) { - // No DD provided - $this->importBookmark($user, $dt); - $dt = null; - } - $dt = $child; - break; - case 'dd': - $dd = $child; - $saved = $this->importBookmark($user, $dt, $dd); - $dt = null; - $dd = null; - case 'p': - common_log(LOG_INFO, 'Skipping the

in the

.'); - break; - default: - common_log(LOG_WARNING, "Unexpected element $child->tagName found in import."); - } - } catch (Exception $e) { - common_log(LOG_ERR, $e->getMessage()); - $dt = $dd = null; - } - } - } + $dt = null; - function importBookmark($user, $dt, $dd = null) - { - // We have to go squirrelling around in the child nodes - // on the off chance that we've received another
- // as a child. + for ($i = 0; $i < $children->length; $i++) { + try { + $child = $children->item($i); + if ($child->nodeType != XML_ELEMENT_NODE) { + continue; + } + common_log(LOG_INFO, $child->tagName); + switch (strtolower($child->tagName)) { + case 'dt': + if (!empty($dt)) { + // No DD provided + $this->importBookmark($user, $dt); + $dt = null; + } + $dt = $child; + break; + case 'dd': + $dd = $child; - for ($i = 0; $i < $dt->childNodes->length; $i++) { - $child = $dt->childNodes->item($i); - if ($child->nodeType == XML_ELEMENT_NODE) { - if ($child->tagName == 'dt' && !is_null($dd)) { - $this->importBookmark($user, $dt); - $this->importBookmark($user, $child, $dd); - return; - } - } - } + $saved = $this->importBookmark($user, $dt, $dd); - $as = $dt->getElementsByTagName('a'); + $dt = null; + $dd = null; + case 'p': + common_log(LOG_INFO, 'Skipping the

in the

.'); + break; + default: + common_log(LOG_WARNING, + "Unexpected element $child->tagName ". + " found in import."); + } + } catch (Exception $e) { + common_log(LOG_ERR, $e->getMessage()); + $dt = $dd = null; + } + } + } - if ($as->length == 0) { - throw new ClientException(_("No tag in a
.")); - } + /** + * Import a single bookmark + * + * Takes a
/
pair. The
has a single + * in it with some non-standard attributes. + * + * A
sequence will appear as a
with + * anothe
as a child. We handle this case recursively. + * + * @param User $user User to import data as + * @param DOMElement $dt
element + * @param DOMElement $dd
element + * + * @return Notice imported notice + */ - $a = $as->item(0); - - $private = $a->getAttribute('private'); + function importBookmark($user, $dt, $dd = null) + { + // We have to go squirrelling around in the child nodes + // on the off chance that we've received another
+ // as a child. - if ($private != 0) { - throw new ClientException(_('Skipping private bookmark.')); - } + for ($i = 0; $i < $dt->childNodes->length; $i++) { + $child = $dt->childNodes->item($i); + if ($child->nodeType == XML_ELEMENT_NODE) { + if ($child->tagName == 'dt' && !is_null($dd)) { + $this->importBookmark($user, $dt); + $this->importBookmark($user, $child, $dd); + return; + } + } + } - if (!empty($dd)) { - $description = $dd->nodeValue; - } else { - $description = null; - } + $as = $dt->getElementsByTagName('a'); - $title = $a->nodeValue; - $url = $a->getAttribute('href'); - $tags = $a->getAttribute('tags'); - $addDate = $a->getAttribute('add_date'); - $created = common_sql_date(intval($addDate)); + if ($as->length == 0) { + throw new ClientException(_("No tag in a
.")); + } - $saved = Notice_bookmark::saveNew($user, - $title, - $url, - $tags, - $description, - array('created' => $created)); + $a = $as->item(0); + + $private = $a->getAttribute('private'); - return $saved; - } + if ($private != 0) { + throw new ClientException(_('Skipping private bookmark.')); + } - function importHTML($body) - { + if (!empty($dd)) { + $description = $dd->nodeValue; + } else { + $description = null; + } + + $title = $a->nodeValue; + $url = $a->getAttribute('href'); + $tags = $a->getAttribute('tags'); + $addDate = $a->getAttribute('add_date'); + $created = common_sql_date(intval($addDate)); + + $saved = Notice_bookmark::saveNew($user, + $title, + $url, + $tags, + $description, + array('created' => $created)); + + return $saved; + } + + /** + * Parse some HTML + * + * Hides the errors that the dom parser returns + * + * @param string $body Data to import + * + * @return DOMDocument parsed document + */ + + function importHTML($body) + { // DOMDocument::loadHTML may throw warnings on unrecognized elements, // and notices on unrecognized namespaces. $old = error_reporting(error_reporting() & ~(E_WARNING | E_NOTICE)); $dom = new DOMDocument(); - $ok = $dom->loadHTML($body); + $ok = $dom->loadHTML($body); error_reporting($old); - if ($ok) { - return $dom; - } else { - return null; - } - } + if ($ok) { + return $dom; + } else { + return null; + } + } }