3 * StatusNet - the distributed open-source microblogging tool
4 * Copyright (C) 2010, StatusNet, Inc.
6 * Importer for feeds of activities
10 * This program is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU Affero General Public License as published by
12 * the Free Software Foundation, either version 3 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Affero General Public License for more details.
20 * You should have received a copy of the GNU Affero General Public License
21 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 * @author Evan Prodromou <evan@status.net>
26 * @copyright 2010 StatusNet, Inc.
27 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
28 * @link http://status.net/
31 if (!defined('STATUSNET')) {
32 // This check helps protect against security problems;
33 // your code file can't be executed directly from the web.
38 * Importer for feeds of activities
40 * Takes an XML file representing a feed of activities and imports each
41 * activity to the user in question.
45 * @author Evan Prodromou <evan@status.net>
46 * @copyright 2010 StatusNet, Inc.
47 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
48 * @link http://status.net/
50 class FeedImporter extends QueueHandler
53 * Transport identifier
55 * @return string identifier for this queue handler
57 public function transport()
62 function handle($data)
64 list($user, $xml, $trusted) = $data;
67 $doc = DOMDocument::loadXML($xml);
69 $feed = $doc->documentElement;
71 if ($feed->namespaceURI != Activity::ATOM ||
72 $feed->localName != 'feed') {
73 // TRANS: Client exception thrown when an imported feed is not an Atom feed.
74 throw new ClientException(_("Not an Atom feed."));
78 $author = ActivityUtils::getFeedAuthor($feed);
81 // TRANS: Client exception thrown when an imported feed does not have an author.
82 throw new ClientException(_("No author in the feed."));
87 $user = $this->userFromAuthor($author);
89 // TRANS: Client exception thrown when an imported feed does not have an author that
90 // TRANS: can be associated with a user.
91 throw new ClientException(_("Cannot import without a user."));
95 $activities = $this->getActivities($feed);
97 $qm = QueueManager::get();
99 foreach ($activities as $activity) {
100 $qm->enqueue(array($user, $author, $activity, $trusted), 'actimp');
102 } catch (ClientException $ce) {
103 common_log(LOG_WARNING, $ce->getMessage());
105 } catch (ServerException $se) {
106 common_log(LOG_ERR, $ce->getMessage());
108 } catch (Exception $e) {
109 common_log(LOG_ERR, $ce->getMessage());
114 function getActivities($feed)
116 $entries = $feed->getElementsByTagNameNS(Activity::ATOM, 'entry');
118 $activities = array();
120 for ($i = 0; $i < $entries->length; $i++) {
121 $activities[] = new Activity($entries->item($i));
124 usort($activities, array("FeedImporter", "activitySort"));
130 * Sort activities oldest-first
132 static function activitySort($a, $b)
134 if ($a->time == $b->time) {
136 } else if ($a->time < $b->time) {
143 function userFromAuthor($author)
145 $user = User::getKV('uri', $author->id);
149 array('nickname' => Ostatus_profile::getActivityObjectNickname($author),
150 'uri' => $author->id);
152 $user = User::register($attrs);
155 $profile = $user->getProfile();
156 Ostatus_profile::updateProfile($profile, $author);
158 // @todo FIXME: Update avatar