4 * StatusNet - the distributed open-source microblogging tool
5 * Copyright (C) 2010 StatusNet, Inc.
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
23 $shortoptions = 'i:n:f:';
24 $longoptions = array('id=', 'nickname=', 'file=');
26 $helptext = <<<END_OF_IMPORTTWITTERATOM_HELP
27 importtwitteratom.php [options]
28 import an Atom feed from Twitter as notices by a user
30 -i --id ID of user to update
31 -n --nickname nickname of the user to update
32 -f --file file to import (Atom-only for now)
34 END_OF_IMPORTTWITTERATOM_HELP;
36 require_once INSTALLDIR.'/scripts/commandline.inc';
37 require_once INSTALLDIR.'/extlib/htmLawed/htmLawed.php';
43 if (have_option('i', 'id')) {
44 $id = get_option_value('i', 'id');
45 $user = User::staticGet('id', $id);
47 throw new Exception("Can't find user with id '$id'.");
49 } else if (have_option('n', 'nickname')) {
50 $nickname = get_option_value('n', 'nickname');
51 $user = User::staticGet('nickname', $nickname);
53 throw new Exception("Can't find user with nickname '$nickname'");
63 function getAtomFeedDocument()
65 $filename = get_option_value('f', 'file');
67 if (empty($filename)) {
72 if (!file_exists($filename)) {
73 throw new Exception("No such file '$filename'.");
76 if (!is_file($filename)) {
77 throw new Exception("Not a regular file: '$filename'.");
80 if (!is_readable($filename)) {
81 throw new Exception("File '$filename' not readable.");
84 $xml = file_get_contents($filename);
86 $dom = DOMDocument::loadXML($xml);
88 if ($dom->documentElement->namespaceURI != Activity::ATOM ||
89 $dom->documentElement->localName != 'feed') {
90 throw new Exception("'$filename' is not an Atom feed.");
96 function importActivityStream($user, $doc)
98 $feed = $doc->documentElement;
100 $entries = $feed->getElementsByTagNameNS(Activity::ATOM, 'entry');
102 for ($i = $entries->length - 1; $i >= 0; $i--) {
103 $entry = $entries->item($i);
104 $activity = new Activity($entry, $feed);
105 $object = $activity->object;
106 if (!have_option('q', 'quiet')) {
107 print $activity->content . "\n";
109 $html = getTweetHtml($object->link);
111 $config = array('safe' => 1,
112 'deny_attribute' => 'class,rel,id,style,on*');
114 $html = htmLawed($html, $config);
116 $content = html_entity_decode(strip_tags($html));
118 $notice = Notice::saveNew($user->id,
121 array('uri' => $object->id,
122 'url' => $object->link,
124 'created' => common_sql_date($activity->time),
125 'replies' => array(),
126 'groups' => array()));
130 function getTweetHtml($url)
133 $client = new HTTPClient();
134 $response = $client->get($url);
135 } catch (HTTP_Request2_Exception $e) {
136 print "ERROR: HTTP response " . $e->getMessage() . "\n";
140 if (!$response->isOk()) {
141 print "ERROR: HTTP response " . $response->getCode() . "\n";
145 $body = $response->getBody();
147 return tweetHtmlFromBody($body);
150 function tweetHtmlFromBody($body)
152 $doc = DOMDocument::loadHTML($body);
153 $xpath = new DOMXPath($doc);
155 $spans = $xpath->query('//span[@class="entry-content"]');
157 if ($spans->length == 0) {
158 print "ERROR: No content in tweet page.\n";
162 $span = $spans->item(0);
164 $children = $span->childNodes;
168 for ($i = 0; $i < $children->length; $i++) {
169 $child = $children->item($i);
170 if ($child instanceof DOMElement &&
171 $child->tagName == 'a' &&
172 !preg_match('#^https?://#', $child->getAttribute('href'))) {
173 $child->setAttribute('href', 'http://twitter.com' . $child->getAttribute('href'));
175 $text .= $doc->saveXML($child);
183 $doc = getAtomFeedDocument();
186 importActivityStream($user, $doc);
188 } catch (Exception $e) {
189 print $e->getMessage()."\n";