activitymover.php 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. <?php
  2. /**
  3. * StatusNet - the distributed open-source microblogging tool
  4. * Copyright (C) 2010, StatusNet, Inc.
  5. *
  6. * Title of module
  7. *
  8. * PHP version 5
  9. *
  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.
  14. *
  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.
  19. *
  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/>.
  22. *
  23. * @category Cache
  24. * @package StatusNet
  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/
  29. */
  30. if (!defined('STATUSNET')) {
  31. // This check helps protect against security problems;
  32. // your code file can't be executed directly from the web.
  33. exit(1);
  34. }
  35. /**
  36. * Class comment
  37. *
  38. * @category General
  39. * @package StatusNet
  40. * @author Evan Prodromou <evan@status.net>
  41. * @copyright 2010 StatusNet, Inc.
  42. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
  43. * @link http://status.net/
  44. */
  45. class ActivityMover extends QueueHandler
  46. {
  47. function transport()
  48. {
  49. return 'actmove';
  50. }
  51. function handle($data)
  52. {
  53. list ($act, $sink, $userURI, $remoteURI) = $data;
  54. $user = User::getKV('uri', $userURI);
  55. try {
  56. $remote = Profile::fromUri($remoteURI);
  57. } catch (UnknownUriException $e) {
  58. // Don't retry. It's hard to tell whether it's because of
  59. // lookup failures or because the URI is permanently gone.
  60. // If we knew it was temporary, we'd return false here.
  61. return true;
  62. }
  63. try {
  64. $this->moveActivity($act, $sink, $user, $remote);
  65. } catch (ClientException $cex) {
  66. $this->log(LOG_WARNING,
  67. $cex->getMessage());
  68. // "don't retry me"
  69. return true;
  70. } catch (ServerException $sex) {
  71. $this->log(LOG_WARNING,
  72. $sex->getMessage());
  73. // "retry me" (because we think the server might handle it next time)
  74. return false;
  75. } catch (Exception $ex) {
  76. $this->log(LOG_WARNING,
  77. $ex->getMessage());
  78. // "don't retry me"
  79. return true;
  80. }
  81. }
  82. function moveActivity($act, $sink, $user, $remote)
  83. {
  84. if (empty($user)) {
  85. // TRANS: Exception thrown if a non-existing user is provided. %s is a user ID.
  86. throw new Exception(sprintf(_('No such user "%s".'),$act->actor->id));
  87. }
  88. switch ($act->verb) {
  89. /* case ActivityVerb::FAVORITE:
  90. $this->log(LOG_INFO,
  91. "Moving favorite of {$act->objects[0]->id} by ".
  92. "{$act->actor->id} to {$remote->nickname}.");
  93. // push it, then delete local
  94. $sink->postActivity($act);
  95. $notice = Notice::getKV('uri', $act->objects[0]->id);
  96. if (!empty($notice)) {
  97. $fave = Fave::pkeyGet(array('user_id' => $user->id,
  98. 'notice_id' => $notice->id));
  99. $fave->delete();
  100. }
  101. break;*/
  102. case ActivityVerb::POST:
  103. $this->log(LOG_INFO,
  104. "Moving notice {$act->objects[0]->id} by ".
  105. "{$act->actor->id} to {$remote->nickname}.");
  106. // XXX: send a reshare, not a post
  107. $sink->postActivity($act);
  108. $notice = Notice::getKV('uri', $act->objects[0]->id);
  109. if (!empty($notice)) {
  110. $notice->deleteAs($user->getProfile(), false);
  111. }
  112. break;
  113. case ActivityVerb::JOIN:
  114. $this->log(LOG_INFO,
  115. "Moving group join of {$act->objects[0]->id} by ".
  116. "{$act->actor->id} to {$remote->nickname}.");
  117. $sink->postActivity($act);
  118. $group = User_group::getKV('uri', $act->objects[0]->id);
  119. if (!empty($group)) {
  120. $user->leaveGroup($group);
  121. }
  122. break;
  123. case ActivityVerb::FOLLOW:
  124. if ($act->actor->id === $user->getUri()) {
  125. $this->log(LOG_INFO,
  126. "Moving subscription to {$act->objects[0]->id} by ".
  127. "{$act->actor->id} to {$remote->nickname}.");
  128. $sink->postActivity($act);
  129. try {
  130. $other = Profile::fromUri($act->objects[0]->id);
  131. Subscription::cancel($user->getProfile(), $other);
  132. } catch (UnknownUriException $e) {
  133. // Can't cancel subscription if we don't know who to alert
  134. }
  135. } else {
  136. $otherUser = User::getKV('uri', $act->actor->id);
  137. if (!empty($otherUser)) {
  138. $this->log(LOG_INFO,
  139. "Changing sub to {$act->objects[0]->id}".
  140. "by {$act->actor->id} to {$remote->nickname}.");
  141. $otherProfile = $otherUser->getProfile();
  142. Subscription::ensureStart($otherProfile, $remote);
  143. Subscription::cancel($otherProfile, $user->getProfile());
  144. } else {
  145. $this->log(LOG_NOTICE,
  146. "Not changing sub to {$act->objects[0]->id}".
  147. "by remote {$act->actor->id} ".
  148. "to {$remote->nickname}.");
  149. }
  150. }
  151. break;
  152. }
  153. }
  154. /**
  155. * Log some data
  156. *
  157. * Add a header for our class so we know who did it.
  158. *
  159. * @param int $level Log level, like LOG_ERR or LOG_INFO
  160. * @param string $message Message to log
  161. *
  162. * @return void
  163. */
  164. protected function log($level, $message)
  165. {
  166. common_log($level, "ActivityMover: " . $message);
  167. }
  168. }