From c579bcae7b9f42738fa3880c0998420bac7d5fae Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Fri, 15 Jul 2011 12:49:52 -0400 Subject: [PATCH] conversation API --- actions/apiconversation.php | 242 ++++++++++++++++++++++++++++++++++++ lib/router.php | 5 + 2 files changed, 247 insertions(+) create mode 100644 actions/apiconversation.php diff --git a/actions/apiconversation.php b/actions/apiconversation.php new file mode 100644 index 0000000000..fefb5b67a5 --- /dev/null +++ b/actions/apiconversation.php @@ -0,0 +1,242 @@ +. + * + * @category API + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +require_once INSTALLDIR . '/lib/apiauth.php'; + +/** + * Show a stream of notices in a particular conversation + * + * @category API + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +class ApiconversationAction extends ApiAuthAction +{ + protected $conversation = null; + protected $notices = null; + + /** + * For initializing members of the class. + * + * @param array $argarray misc. arguments + * + * @return boolean true + */ + + function prepare($argarray) + { + parent::prepare($argarray); + + $convId = $this->trimmed('id'); + + if (empty($convId)) { + throw new ClientException(_m('no conversation id')); + } + + $this->conversation = Conversation::staticGet('id', $convId); + + if (empty($this->conversation)) { + throw new ClientException(sprintf(_m('No conversation with id %d'), $convId), + 404); + } + + $profile = Profile::current(); + + $stream = new ConversationNoticeStream($convId, $profile); + + $notice = $stream->getNotices(($this->page-1) * $this->count, + $this->count, + $this->since_id, + $this->max_id); + + $this->notices = $notice->fetchAll(); + + return true; + } + + /** + * Handler method + * + * @param array $argarray is ignored since it's now passed in in prepare() + * + * @return void + */ + + function handle($argarray=null) + { + $sitename = common_config('site', 'name'); + // TRANS: Timeline title for user and friends. %s is a user nickname. + $title = _("Conversation"); + $id = common_local_url('apiconversation', array('id' => $this->conversation->id, 'format' => $this->format)); + $link = common_local_url('conversation', array('id' => $this->conversation->id)); + + $self = $id; + + switch($this->format) { + case 'xml': + $this->showXmlTimeline($this->notices); + break; + case 'rss': + $this->showRssTimeline( + $this->notices, + $title, + $link, + null, + null, + null, + $self + ); + break; + case 'atom': + + header('Content-Type: application/atom+xml; charset=utf-8'); + + $atom = new AtomNoticeFeed($this->auth_user); + + $atom->setId($id); + $atom->setTitle($title); + $atom->setUpdated('now'); + + $atom->addLink($link); + $atom->setSelfLink($self); + + $atom->addEntryFromNotices($this->notices); + $this->raw($atom->getString()); + + break; + case 'json': + $this->showJsonTimeline($this->notices); + break; + case 'as': + header('Content-Type: ' . ActivityStreamJSONDocument::CONTENT_TYPE); + $doc = new ActivityStreamJSONDocument($this->auth_user); + $doc->setTitle($title); + $doc->addLink($link, 'alternate', 'text/html'); + $doc->addItemsFromNotices($this->notices); + $this->raw($doc->asString()); + break; + default: + // TRANS: Client error displayed when coming across a non-supported API method. + $this->clientError(_('API method not found.'), $code = 404); + break; + } + } + + /** + * Return true if read only. + * + * MAY override + * + * @param array $args other arguments + * + * @return boolean is read only action? + */ + + function isReadOnly($args) + { + if ($_SERVER['REQUEST_METHOD'] == 'GET' || + $_SERVER['REQUEST_METHOD'] == 'HEAD') { + return true; + } else { + return false; + } + } + + /** + * Return last modified, if applicable. + * + * MAY override + * + * @return string last modified http header + */ + function lastModified() + { + if (!empty($this->notices) && (count($this->notices) > 0)) { + return strtotime($this->notices[0]->created); + } + + return null; + } + + /** + * Return etag, if applicable. + * + * MAY override + * + * @return string etag http header + */ + + function etag() + { + if (!empty($this->notices) && (count($this->notices) > 0)) { + + $last = count($this->notices) - 1; + + return '"' . implode( + ':', + array($this->arg('action'), + common_user_cache_hash($this->auth_user), + common_language(), + $this->user->id, + strtotime($this->notices[0]->created), + strtotime($this->notices[$last]->created)) + ) + . '"'; + } + + return null; + } + + /** + * Does this require authentication? + * + * @return boolean true if delete, else false + */ + + function requiresAuth() + { + if ($_SERVER['REQUEST_METHOD'] == 'GET' || + $_SERVER['REQUEST_METHOD'] == 'HEAD') { + return false; + } else { + return true; + } + } +} \ No newline at end of file diff --git a/lib/router.php b/lib/router.php index dbf3aaeb97..9c15d7bf24 100644 --- a/lib/router.php +++ b/lib/router.php @@ -774,6 +774,11 @@ class Router array('action' => 'ApiGroupProfileUpdate', 'id' => '[a-zA-Z0-9]+', 'format' => '(xml|json)')); + + $m->connect('api/statusnet/conversation/:id.:format', + array('action' => 'apiconversation', + 'id' => '[0-9]+', + 'format' => '(xml|json|rss|atom|as)')); // Lists (people tags) -- 2.39.5