/** * If a notice gets deleted, remove the Notice_to_status mapping and * delete the status on Twitter. * * @param User $user The user doing the deleting * @param Notice $notice The notice getting deleted * * @return boolean hook value */ function onStartDeleteOwnNotice(User $user, Notice $notice) { $n2s = Notice_to_status::getKV('notice_id', $notice->id); if (!empty($n2s)) { $flink = Foreign_link::getByUserID($notice->profile_id, TWITTER_SERVICE); // twitter service if (empty($flink)) { return true; } if (!TwitterOAuthClient::isPackedToken($flink->credentials)) { $this->log(LOG_INFO, "Skipping deleting notice for {$notice->id} since link is not OAuth."); return true; } try { $token = TwitterOAuthClient::unpackToken($flink->credentials); $client = new TwitterOAuthClient($token->key, $token->secret); $client->statusesDestroy($n2s->status_id); } catch (Exception $e) { common_log(LOG_ERR, "Error attempting to delete bridged notice from Twitter: " . $e->getMessage()); } $n2s->delete(); } return true; }
function saveStatus($status) { $profile = $this->ensureProfile($status->user); if (empty($profile)) { common_log(LOG_ERR, __METHOD__ . ' - Problem saving notice. No associated Profile.'); return null; } $statusId = twitter_id($status); $statusUri = $this->makeStatusURI($status->user->screen_name, $statusId); // check to see if we've already imported the status $n2s = Notice_to_status::getKV('status_id', $statusId); if (!empty($n2s)) { common_log(LOG_INFO, __METHOD__ . " - Ignoring duplicate import: {$statusId}"); return Notice::getKV('id', $n2s->notice_id); } $dupe = Notice::getKV('uri', $statusUri); if ($dupe instanceof Notice) { // Add it to our record Notice_to_status::saveNew($dupe->id, $statusId); common_log(LOG_INFO, __METHOD__ . " - Ignoring duplicate import: {$statusId}"); return $dupe; } // If it's a retweet, save it as a repeat! if (!empty($status->retweeted_status)) { common_log(LOG_INFO, "Status {$statusId} is a retweet of " . twitter_id($status->retweeted_status) . "."); $original = $this->saveStatus($status->retweeted_status); if (empty($original)) { return null; } else { $author = $original->getProfile(); // TRANS: Message used to repeat a notice. RT is the abbreviation of 'retweet'. // TRANS: %1$s is the repeated user's name, %2$s is the repeated notice. $content = sprintf(_m('RT @%1$s %2$s'), $author->nickname, $original->content); if (Notice::contentTooLong($content)) { $contentlimit = Notice::maxContent(); $content = mb_substr($content, 0, $contentlimit - 4) . ' ...'; } $repeat = Notice::saveNew($profile->id, $content, 'twitter', array('repeat_of' => $original->id, 'uri' => $statusUri, 'is_local' => Notice::GATEWAY)); common_log(LOG_INFO, "Saved {$repeat->id} as a repeat of {$original->id}"); Notice_to_status::saveNew($repeat->id, $statusId); return $repeat; } } $notice = new Notice(); $notice->profile_id = $profile->id; $notice->uri = $statusUri; $notice->url = $statusUri; $notice->verb = ActivityVerb::POST; $notice->created = strftime('%Y-%m-%d %H:%M:%S', strtotime($status->created_at)); $notice->source = 'twitter'; $notice->reply_to = null; $replyTo = twitter_id($status, 'in_reply_to_status_id'); if (!empty($replyTo)) { common_log(LOG_INFO, "Status {$statusId} is a reply to status {$replyTo}"); $n2s = Notice_to_status::getKV('status_id', $replyTo); if (empty($n2s)) { common_log(LOG_INFO, "Couldn't find local notice for status {$replyTo}"); } else { $reply = Notice::getKV('id', $n2s->notice_id); if (empty($reply)) { common_log(LOG_INFO, "Couldn't find local notice for status {$replyTo}"); } else { common_log(LOG_INFO, "Found local notice {$reply->id} for status {$replyTo}"); $notice->reply_to = $reply->id; $notice->conversation = $reply->conversation; } } } $notice->is_local = Notice::GATEWAY; $notice->content = html_entity_decode($this->linkify($status, FALSE), ENT_QUOTES, 'UTF-8'); $notice->rendered = $this->linkify($status, TRUE); if (Event::handle('StartNoticeSave', array(&$notice))) { if (empty($notice->conversation)) { $conv = Conversation::create(); common_log(LOG_INFO, "No known conversation for status {$statusId} so a new one ({$conv->getID()}) was created."); $notice->conversation = $conv->getID(); } $id = $notice->insert(); if ($id === false) { common_log_db_error($notice, 'INSERT', __FILE__); common_log(LOG_ERR, __METHOD__ . ' - Problem saving notice.'); } Event::handle('EndNoticeSave', array($notice)); } Notice_to_status::saveNew($notice->id, $statusId); $this->saveStatusMentions($notice, $status); $this->saveStatusAttachments($notice, $status); $notice->blowOnInsert(); return $notice; }
function twitter_status_id($notice) { $n2s = Notice_to_status::getKV('notice_id', $notice->id); if (empty($n2s)) { return null; } else { return $n2s->status_id; } }
/** * Save a mapping between a notice and a status * Warning: status_id values may not fit in 32-bit integers. * * @param integer $notice_id ID of the notice in StatusNet * @param integer $status_id ID of the status in Twitter * * @return Notice_to_status new object for this value */ static function saveNew($notice_id, $status_id) { if (empty($notice_id)) { throw new Exception("Invalid notice_id {$notice_id}"); } $n2s = Notice_to_status::getKV('notice_id', $notice_id); if (!empty($n2s)) { return $n2s; } if (empty($status_id)) { throw new Exception("Invalid status_id {$status_id}"); } $n2s = Notice_to_status::getKV('status_id', $status_id); if (!empty($n2s)) { return $n2s; } common_debug("Mapping notice {$notice_id} to Twitter status {$status_id}"); $n2s = new Notice_to_status(); $n2s->notice_id = $notice_id; $n2s->status_id = $status_id; $n2s->created = common_sql_now(); $n2s->insert(); return $n2s; }