]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
add a script to import Twitter atom feed as notices
authorEvan Prodromou <evan@status.net>
Mon, 8 Mar 2010 04:41:55 +0000 (23:41 -0500)
committerEvan Prodromou <evan@status.net>
Mon, 8 Mar 2010 04:42:22 +0000 (23:42 -0500)
scripts/importtwitteratom.php [new file with mode: 0644]

diff --git a/scripts/importtwitteratom.php b/scripts/importtwitteratom.php
new file mode 100644 (file)
index 0000000..7316f21
--- /dev/null
@@ -0,0 +1,192 @@
+#!/usr/bin/env php
+<?php
+/*
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2010 StatusNet, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
+
+$shortoptions = 'i:n:f:';
+$longoptions = array('id=', 'nickname=', 'file=');
+
+$helptext = <<<END_OF_IMPORTTWITTERATOM_HELP
+importtwitteratom.php [options]
+import an Atom feed from Twitter as notices by a user
+
+  -i --id       ID of user to update
+  -n --nickname nickname of the user to update
+  -f --file     file to import (Atom-only for now)
+
+END_OF_IMPORTTWITTERATOM_HELP;
+
+require_once INSTALLDIR.'/scripts/commandline.inc';
+require_once INSTALLDIR.'/extlib/htmLawed/htmLawed.php';
+
+function getUser()
+{
+    $user = null;
+
+    if (have_option('i', 'id')) {
+        $id = get_option_value('i', 'id');
+        $user = User::staticGet('id', $id);
+        if (empty($user)) {
+            throw new Exception("Can't find user with id '$id'.");
+        }
+    } else if (have_option('n', 'nickname')) {
+        $nickname = get_option_value('n', 'nickname');
+        $user = User::staticGet('nickname', $nickname);
+        if (empty($user)) {
+            throw new Exception("Can't find user with nickname '$nickname'");
+        }
+    } else {
+        show_help();
+        exit(1);
+    }
+
+    return $user;
+}
+
+function getAtomFeedDocument()
+{
+    $filename = get_option_value('f', 'file');
+
+    if (empty($filename)) {
+        show_help();
+        exit(1);
+    }
+
+    if (!file_exists($filename)) {
+        throw new Exception("No such file '$filename'.");
+    }
+
+    if (!is_file($filename)) {
+        throw new Exception("Not a regular file: '$filename'.");
+    }
+
+    if (!is_readable($filename)) {
+        throw new Exception("File '$filename' not readable.");
+    }
+
+    $xml = file_get_contents($filename);
+
+    $dom = DOMDocument::loadXML($xml);
+
+    if ($dom->documentElement->namespaceURI != Activity::ATOM ||
+        $dom->documentElement->localName != 'feed') {
+        throw new Exception("'$filename' is not an Atom feed.");
+    }
+
+    return $dom;
+}
+
+function importActivityStream($user, $doc)
+{
+    $feed = $doc->documentElement;
+
+    $entries = $feed->getElementsByTagNameNS(Activity::ATOM, 'entry');
+
+    for ($i = $entries->length - 1; $i >= 0; $i--) {
+        $entry = $entries->item($i);
+        $activity = new Activity($entry, $feed);
+        $object = $activity->object;
+        if (!have_option('q', 'quiet')) {
+            print $activity->content . "\n";
+        }
+        $html = getTweetHtml($object->link);
+
+        $config = array('safe' => 1,
+                        'deny_attribute' => 'class,rel,id,style,on*');
+
+        $html = htmLawed($html, $config);
+
+        $content = html_entity_decode(strip_tags($html));
+
+        $notice = Notice::saveNew($user->id,
+                                  $content,
+                                  'importtwitter',
+                                  array('uri' => $object->id,
+                                        'url' => $object->link,
+                                        'rendered' => $html,
+                                        'created' => common_sql_date($activity->time),
+                                        'replies' => array(),
+                                        'groups' => array()));
+    }
+}
+
+function getTweetHtml($url)
+{
+    try {
+        $client = new HTTPClient();
+        $response = $client->get($url);
+    } catch (HTTP_Request2_Exception $e) {
+        print "ERROR: HTTP response " . $e->getMessage() . "\n";
+        return false;
+    }
+
+    if (!$response->isOk()) {
+        print "ERROR: HTTP response " . $response->getCode() . "\n";
+        return false;
+    }
+
+    $body = $response->getBody();
+
+    return tweetHtmlFromBody($body);
+}
+
+function tweetHtmlFromBody($body)
+{
+    $doc = DOMDocument::loadHTML($body);
+    $xpath = new DOMXPath($doc);
+
+    $spans = $xpath->query('//span[@class="entry-content"]');
+
+    if ($spans->length == 0) {
+        print "ERROR: No content in tweet page.\n";
+        return '';
+    }
+
+    $span = $spans->item(0);
+
+    $children = $span->childNodes;
+
+    $text = '';
+
+    for ($i = 0; $i < $children->length; $i++) {
+        $child = $children->item($i);
+        if ($child instanceof DOMElement &&
+            $child->tagName == 'a' &&
+            !preg_match('#^https?://#', $child->getAttribute('href'))) {
+            $child->setAttribute('href', 'http://twitter.com' . $child->getAttribute('href'));
+        }
+        $text .= $doc->saveXML($child);
+    }
+
+    return $text;
+}
+
+try {
+
+    $doc = getAtomFeedDocument();
+    $user = getUser();
+
+    importActivityStream($user, $doc);
+
+} catch (Exception $e) {
+    print $e->getMessage()."\n";
+    exit(1);
+}
+