X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=scripts%2Fmoveuser.php;h=ff08ee24ce3ac60e8e03b03e7f3b2c543f394495;hb=26703076f66f77f337559416cc02101c532d7aa8;hp=feaca15103b8e390c5d376444efeaf94a8bc92b1;hpb=4690d0c0dbe91d2bf6bb3a6969e380f44d328517;p=quix0rs-gnu-social.git diff --git a/scripts/moveuser.php b/scripts/moveuser.php index feaca15103..ff08ee24ce 100644 --- a/scripts/moveuser.php +++ b/scripts/moveuser.php @@ -19,7 +19,7 @@ define('INSTALLDIR', realpath(dirname(__FILE__) . '/..')); -$shortoptions = 'i:n:r:w:'; +$shortoptions = 'i:n:r:w:y'; $longoptions = array('id=', 'nickname=', 'remote=', 'password='); $helptext = <<svcDocUrl = $svcDocUrl; - $this->username = $username; - $this->password = $password; - - $this->_parseSvcDoc(); - } - - private function _parseSvcDoc() - { - $client = new HTTPClient(); - $response = $client->get($this->svcDocUrl); - - if ($response->getStatus() != 200) { - throw new Exception("Can't get {$this->svcDocUrl}; response status " . $response->getStatus()); - } - - $xml = $response->getBody(); - - $dom = new DOMDocument(); - - // We don't want to bother with white spaces - $dom->preserveWhiteSpace = false; - - // Don't spew XML warnings to output - $old = error_reporting(); - error_reporting($old & ~E_WARNING); - $ok = $dom->loadXML($xml); - error_reporting($old); - - $path = new DOMXPath($dom); - - $path->registerNamespace('atom', 'http://www.w3.org/2005/Atom'); - $path->registerNamespace('app', 'http://www.w3.org/2007/app'); - $path->registerNamespace('activity', 'http://activitystrea.ms/spec/1.0/'); - - $collections = $path->query('//app:collection'); - - for ($i = 0; $i < $collections->length; $i++) { - $collection = $collections->item($i); - $url = $collection->getAttribute('href'); - $takesEntries = false; - $accepts = $path->query('app:accept', $collection); - for ($j = 0; $j < $accepts->length; $j++) { - $accept = $accepts->item($j); - $acceptValue = $accept->nodeValue; - if (preg_match('#application/atom\+xml(;\s*type=entry)?#', $acceptValue)) { - $takesEntries = true; - break; - } - } - if (!$takesEntries) { - continue; - } - $verbs = $path->query('activity:verb', $collection); - if ($verbs->length == 0) { - $this->_addCollection(ActivityVerb::POST, $url); - } else { - for ($k = 0; $k < $verbs->length; $k++) { - $verb = $verbs->item($k); - $this->_addCollection($verb->nodeValue, $url); - } - } - } - } - - private function _addCollection($verb, $url) - { - if (array_key_exists($verb, $this->collections)) { - $this->collections[$verb][] = $url; - } else { - $this->collections[$verb] = array($url); - } - return; - } - - function postActivity($activity) - { - if (!array_key_exists($activity->verb, $this->collections)) { - throw new Exception("No collection for verb {$activity->verb}"); - } else { - if (count($this->collections[$activity->verb]) > 1) { - common_log(LOG_NOTICE, "More than one collection for verb {$activity->verb}"); - } - $this->postToCollection($this->collections[$activity->verb][0], $activity); - } - } - - function postToCollection($url, $activity) - { - $client = new HTTPClient($url); - - $client->setMethod('POST'); - $client->setAuth($this->username, $this->password); - $client->setHeader('Content-Type', 'application/atom+xml;type=entry'); - $client->setBody($activity->asString(true, true, true)); - - $response = $client->send(); - } -} - -function getServiceDocument($remote) -{ - $discovery = new Discovery(); - - $xrd = $discovery->lookup($remote); - - if (empty($xrd)) { - throw new Exception("Can't find XRD for $remote"); - } - - $svcDocUrl = null; - $username = null; - - foreach ($xrd->links as $link) { - if ($link['rel'] == 'http://apinamespace.org/atom' && - $link['type'] == 'application/atomsvc+xml') { - $svcDocUrl = $link['href']; - if (!empty($link['property'])) { - foreach ($link['property'] as $property) { - if ($property['type'] == 'http://apinamespace.org/atom/username') { - $username = $property['value']; - break; - } - } - } - break; - } - } - - if (empty($svcDocUrl)) { - throw new Exception("No AtomPub API service for $remote."); - } - - return array($svcDocUrl, $username); -} - -class AccountMover -{ - private $_user = null; - private $_profile = null; - private $_remote = null; - private $_sink = null; - - function __construct($user, $remote, $password) - { - $this->_user = $user; - $this->_profile = $user->getProfile(); - - $oprofile = Ostatus_profile::ensureProfileURI($remote); - - if (empty($oprofile)) { - throw new Exception("Can't locate account {$remote}"); - } - - $this->_remote = $oprofile->localProfile(); - - list($svcDocUrl, $username) = getServiceDocument($remote); - - $this->_sink = new ActivitySink($svcDocUrl, $username, $password); - } - - function move() - { - $stream = new UserActivityStream($this->_user); - - $acts = array_reverse($stream->activities); - - // Reverse activities to run in correct chron order - - foreach ($acts as $act) { - $this->_moveActivity($act); - } - } - - private function _moveActivity($act) - { - switch ($act->verb) { - case ActivityVerb::FAVORITE: - // push it, then delete local - $this->_sink->postActivity($act); - $notice = Notice::staticGet('uri', $act->objects[0]->id); - if (!empty($notice)) { - $fave = Fave::pkeyGet(array('user_id' => $this->_user->id, - 'notice_id' => $notice->id)); - $fave->delete(); - } - break; - case ActivityVerb::POST: - // XXX: send a reshare, not a post - common_log(LOG_INFO, "Pushing notice {$act->objects[0]->id} to {$this->_remote->getURI()}"); - $this->_sink->postActivity($act); - $notice = Notice::staticGet('uri', $act->objects[0]->id); - if (!empty($notice)) { - $notice->delete(); - } - break; - case ActivityVerb::JOIN: - $this->_sink->postActivity($act); - $group = User_group::staticGet('uri', $act->objects[0]->id); - if (!empty($group)) { - Group_member::leave($group->id, $this->_user->id); - } - break; - case ActivityVerb::FOLLOW: - if ($act->actor->id == $this->_user->uri) { - $this->_sink->postActivity($act); - $other = Profile::fromURI($act->objects[0]->id); - if (!empty($other)) { - Subscription::cancel($this->_profile, $other); - } - } else { - $otherUser = User::staticGet('uri', $act->actor->id); - if (!empty($otherUser)) { - $otherProfile = $otherUser->getProfile(); - Subscription::start($otherProfile, $this->_remote); - Subscription::cancel($otherProfile, $this->_user->getProfile()); - } else { - // It's a remote subscription. Do something here! - } - } - break; - } - } -} +require_once INSTALLDIR.'/scripts/commandline.inc.php'; try { @@ -286,9 +52,20 @@ try { $password = get_option_value('w', 'password'); - $mover = new AccountMover($user, $remote, $password); + if (!have_option('y', 'yes')) { + print "WARNING: EXPERIMENTAL FEATURE! Moving accounts will delete data from the source site.\n"; + print "\n"; + print "About to PERMANENTLY move user '{$user->nickname}' to $remote. Are you sure? [y/N] "; + $response = fgets(STDIN); + if (strtolower(trim($response)) != 'y') { + print "Aborting.\n"; + exit(0); + } + } + + $qm = QueueManager::get(); - $mover->move(); + $qm->enqueue(array($user, $remote, $password), 'acctmove'); } catch (Exception $e) { print $e->getMessage()."\n";