From ec155464765db36591bbb183b335abbc1ec8638c Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Fri, 11 Jun 2010 11:52:06 -0700 Subject: Fix a couple bad format entries in router setup (format param had 'xmljson' instead of 'xml|json'). Warning: the format strings aren't actually being enforced here which is probably why they weren't caught earlier. Not quite sure why, it should be looked at! --- lib/router.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/router.php') diff --git a/lib/router.php b/lib/router.php index afe44f92a..f2b2b845f 100644 --- a/lib/router.php +++ b/lib/router.php @@ -540,7 +540,7 @@ class Router $m->connect('api/favorites/:id.:format', array('action' => 'ApiTimelineFavorites', 'id' => '[a-zA-Z0-9]+', - 'format' => '(xmljson|rss|atom)')); + 'format' => '(xml|json|rss|atom)')); $m->connect('api/favorites/create/:id.:format', array('action' => 'ApiFavoriteCreate', @@ -597,7 +597,7 @@ class Router $m->connect('api/statusnet/groups/timeline/:id.:format', array('action' => 'ApiTimelineGroup', 'id' => '[a-zA-Z0-9]+', - 'format' => '(xmljson|rss|atom)')); + 'format' => '(xml|json|rss|atom)')); $m->connect('api/statusnet/groups/show.:format', array('action' => 'ApiGroupShow', @@ -658,7 +658,7 @@ class Router // Tags $m->connect('api/statusnet/tags/timeline/:tag.:format', array('action' => 'ApiTimelineTag', - 'format' => '(xmljson|rss|atom)')); + 'format' => '(xml|json|rss|atom)')); // media related $m->connect( -- cgit v1.2.3-54-g00ecf From 327ed5b87e492380bc651ed03159ae7cd3a4a493 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 14 Jun 2010 15:51:49 -0400 Subject: fix URL regex for tags to use UTF-8 --- lib/router.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'lib/router.php') diff --git a/lib/router.php b/lib/router.php index f2b2b845f..fec229c9b 100644 --- a/lib/router.php +++ b/lib/router.php @@ -263,7 +263,7 @@ class Router $m->connect('tag', array('action' => 'publictagcloud')); $m->connect('tag/:tag/rss', array('action' => 'tagrss'), - array('tag' => '[a-zA-Z0-9]+')); + array('tag' => '[\pL\pN_\-\.]{1,64}')); $m->connect('tag/:tag', array('action' => 'tag'), array('tag' => '[\pL\pN_\-\.]{1,64}')); @@ -749,12 +749,12 @@ class Router $m->connect('tag/:tag/rss', array('action' => 'userrss', 'nickname' => $nickname), - array('tag' => '[a-zA-Z0-9]+')); + array('tag' => '[\pL\pN_\-\.]{1,64}')); $m->connect('tag/:tag', array('action' => 'showstream', 'nickname' => $nickname), - array('tag' => '[a-zA-Z0-9]+')); + array('tag' => '[\pL\pN_\-\.]{1,64}')); $m->connect('rsd.xml', array('action' => 'rsd', @@ -815,12 +815,12 @@ class Router $m->connect(':nickname/tag/:tag/rss', array('action' => 'userrss'), array('nickname' => '[a-zA-Z0-9]{1,64}'), - array('tag' => '[a-zA-Z0-9]+')); + array('tag' => '[\pL\pN_\-\.]{1,64}')); $m->connect(':nickname/tag/:tag', array('action' => 'showstream'), array('nickname' => '[a-zA-Z0-9]{1,64}'), - array('tag' => '[a-zA-Z0-9]+')); + array('tag' => '[\pL\pN_\-\.]{1,64}')); $m->connect(':nickname/rsd.xml', array('action' => 'rsd'), -- cgit v1.2.3-54-g00ecf From 9eb5a976b03fae6bd1e1fce6abfe4a6c7964d1ae Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Thu, 24 Jun 2010 18:11:50 -0700 Subject: Have API methods for search subclass ApiPrivateAuthAction --- actions/apisearchatom.php | 408 ++++++++++++++++++++++++++++++++++++++++++ actions/apisearchjson.php | 154 ++++++++++++++++ actions/apitrends.php | 90 ++++++++++ actions/twitapisearchatom.php | 402 ----------------------------------------- actions/twitapisearchjson.php | 151 ---------------- actions/twitapitrends.php | 88 --------- lib/router.php | 6 +- 7 files changed, 655 insertions(+), 644 deletions(-) create mode 100644 actions/apisearchatom.php create mode 100644 actions/apisearchjson.php create mode 100644 actions/apitrends.php delete mode 100644 actions/twitapisearchatom.php delete mode 100644 actions/twitapisearchjson.php delete mode 100644 actions/twitapitrends.php (limited to 'lib/router.php') diff --git a/actions/apisearchatom.php b/actions/apisearchatom.php new file mode 100644 index 000000000..60bb8b040 --- /dev/null +++ b/actions/apisearchatom.php @@ -0,0 +1,408 @@ +. + * + * @category Search + * @package StatusNet + * @author Zach Copley + * @copyright 2008-2010 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET') && !defined('LACONICA')) { + exit(1); +} + +require_once INSTALLDIR.'/lib/apiprivateauth.php'; + +/** + * Action for outputting search results in Twitter compatible Atom + * format. + * + * TODO: abstract Atom stuff into a ruseable base class like + * RSS10Action. + * + * @category Search + * @package StatusNet + * @author Zach Copley + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://status.net/ + * + * @see ApiPrivateAuthAction + */ + +class ApiSearchAtomAction extends ApiPrivateAuthAction +{ + + var $cnt; + var $query; + var $lang; + var $rpp; + var $page; + var $since_id; + var $geocode; + + /** + * Constructor + * + * Just wraps the Action constructor. + * + * @param string $output URI to output to, default = stdout + * @param boolean $indent Whether to indent output, default true + * + * @see Action::__construct + */ + + function __construct($output='php://output', $indent=null) + { + parent::__construct($output, $indent); + } + + /** + * Do we need to write to the database? + * + * @return boolean true + */ + + function isReadonly() + { + return true; + } + + /** + * Read arguments and initialize members + * + * @param array $args Arguments from $_REQUEST + * + * @return boolean success + * + */ + + function prepare($args) + { + common_debug("in apisearchatom prepare()"); + + parent::prepare($args); + + + $this->query = $this->trimmed('q'); + $this->lang = $this->trimmed('lang'); + $this->rpp = $this->trimmed('rpp'); + + if (!$this->rpp) { + $this->rpp = 15; + } + + if ($this->rpp > 100) { + $this->rpp = 100; + } + + $this->page = $this->trimmed('page'); + + if (!$this->page) { + $this->page = 1; + } + + // TODO: Suppport since_id -- we need to tweak the backend + // Search classes to support it. + + $this->since_id = $this->trimmed('since_id'); + $this->geocode = $this->trimmed('geocode'); + + // TODO: Also, language and geocode + + return true; + } + + /** + * Handle a request + * + * @param array $args Arguments from $_REQUEST + * + * @return void + */ + + function handle($args) + { + parent::handle($args); + common_debug("In apisearchatom handle()"); + $this->showAtom(); + } + + /** + * Get the notices to output as results. This also sets some class + * attrs so we can use them to calculate pagination, and output + * since_id and max_id. + * + * @return array an array of Notice objects sorted in reverse chron + */ + + function getNotices() + { + // TODO: Support search operators like from: and to:, boolean, etc. + + $notices = array(); + $notice = new Notice(); + + // lcase it for comparison + $q = strtolower($this->query); + + $search_engine = $notice->getSearchEngine('notice'); + $search_engine->set_sort_mode('chron'); + $search_engine->limit(($this->page - 1) * $this->rpp, + $this->rpp + 1, true); + if (false === $search_engine->query($q)) { + $this->cnt = 0; + } else { + $this->cnt = $notice->find(); + } + + $cnt = 0; + $this->max_id = 0; + + if ($this->cnt > 0) { + while ($notice->fetch()) { + + ++$cnt; + + if (!$this->max_id) { + $this->max_id = $notice->id; + } + + if ($cnt > $this->rpp) { + break; + } + + $notices[] = clone($notice); + } + } + + return $notices; + } + + /** + * Output search results as an Atom feed + * + * @return void + */ + + function showAtom() + { + $notices = $this->getNotices(); + + $this->initAtom(); + $this->showFeed(); + + foreach ($notices as $n) { + + $profile = $n->getProfile(); + + // Don't show notices from deleted users + + if (!empty($profile)) { + $this->showEntry($n); + } + } + + $this->endAtom(); + } + + /** + * Show feed specific Atom elements + * + * @return void + */ + + function showFeed() + { + // TODO: A9 OpenSearch stuff like search.twitter.com? + + $server = common_config('site', 'server'); + $sitename = common_config('site', 'name'); + + // XXX: Use xmlns:statusnet instead? + + $this->elementStart('feed', + array('xmlns' => 'http://www.w3.org/2005/Atom', + + // XXX: xmlns:twitter causes Atom validation to fail + // It's used for the source attr on notices + + 'xmlns:twitter' => 'http://api.twitter.com/', + 'xml:lang' => 'en-US')); // XXX Other locales ? + + $taguribase = TagURI::base(); + $this->element('id', null, "tag:$taguribase:search/$server"); + + $site_uri = common_path(false); + + $search_uri = $site_uri . 'api/search.atom?q=' . urlencode($this->query); + + if ($this->rpp != 15) { + $search_uri .= '&rpp=' . $this->rpp; + } + + // FIXME: this alternate link is not quite right because our + // web-based notice search doesn't support a rpp (responses per + // page) param yet + + $this->element('link', array('type' => 'text/html', + 'rel' => 'alternate', + 'href' => $site_uri . 'search/notice?q=' . + urlencode($this->query))); + + // self link + + $self_uri = $search_uri; + $self_uri .= ($this->page > 1) ? '&page=' . $this->page : ''; + + $this->element('link', array('type' => 'application/atom+xml', + 'rel' => 'self', + 'href' => $self_uri)); + + $this->element('title', null, "$this->query - $sitename Search"); + $this->element('updated', null, common_date_iso8601('now')); + + // XXX: The below "rel" links are not valid Atom, but it's what + // Twitter does... + + // refresh link + + $refresh_uri = $search_uri . "&since_id=" . $this->max_id; + + $this->element('link', array('type' => 'application/atom+xml', + 'rel' => 'refresh', + 'href' => $refresh_uri)); + + // pagination links + + if ($this->cnt > $this->rpp) { + + $next_uri = $search_uri . "&max_id=" . $this->max_id . + '&page=' . ($this->page + 1); + + $this->element('link', array('type' => 'application/atom+xml', + 'rel' => 'next', + 'href' => $next_uri)); + } + + if ($this->page > 1) { + + $previous_uri = $search_uri . "&max_id=" . $this->max_id . + '&page=' . ($this->page - 1); + + $this->element('link', array('type' => 'application/atom+xml', + 'rel' => 'previous', + 'href' => $previous_uri)); + } + + } + + /** + * Build an Atom entry similar to search.twitter.com's based on + * a given notice + * + * @param Notice $notice the notice to use + * + * @return void + */ + + function showEntry($notice) + { + $server = common_config('site', 'server'); + $profile = $notice->getProfile(); + $nurl = common_local_url('shownotice', array('notice' => $notice->id)); + + $this->elementStart('entry'); + + $taguribase = TagURI::base(); + + $this->element('id', null, "tag:$taguribase:$notice->id"); + $this->element('published', null, common_date_w3dtf($notice->created)); + $this->element('link', array('type' => 'text/html', + 'rel' => 'alternate', + 'href' => $nurl)); + $this->element('title', null, common_xml_safe_str(trim($notice->content))); + $this->element('content', array('type' => 'html'), $notice->rendered); + $this->element('updated', null, common_date_w3dtf($notice->created)); + $this->element('link', array('type' => 'image/png', + // XXX: Twitter uses rel="image" (not valid) + 'rel' => 'related', + 'href' => $profile->avatarUrl())); + + // @todo: Here is where we'd put in a link to an atom feed for threads + + $source = null; + + $ns = $notice->getSource(); + if ($ns) { + if (!empty($ns->name) && !empty($ns->url)) { + $source = '' + . htmlspecialchars($ns->name) + . ''; + } else { + $source = $ns->code; + } + } + + $this->element("twitter:source", null, $source); + + $this->elementStart('author'); + + $name = $profile->nickname; + + if ($profile->fullname) { + $name .= ' (' . $profile->fullname . ')'; + } + + $this->element('name', null, $name); + $this->element('uri', null, common_profile_uri($profile)); + $this->elementEnd('author'); + + $this->elementEnd('entry'); + } + + /** + * Initialize the Atom output, send headers + * + * @return void + */ + + function initAtom() + { + header('Content-Type: application/atom+xml; charset=utf-8'); + $this->startXml(); + } + + /** + * End the Atom feed + * + * @return void + */ + + function endAtom() + { + $this->elementEnd('feed'); + } + +} diff --git a/actions/apisearchjson.php b/actions/apisearchjson.php new file mode 100644 index 000000000..e44634684 --- /dev/null +++ b/actions/apisearchjson.php @@ -0,0 +1,154 @@ +. + * + * @category Search + * @package StatusNet + * @author Zach Copley + * @copyright 2008-2010 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET') && !defined('LACONICA')) { + exit(1); +} + +require_once INSTALLDIR.'/lib/apiprivateauth.php'; +require_once INSTALLDIR.'/lib/jsonsearchresultslist.php'; + +/** + * Action handler for Twitter-compatible API search + * + * @category Search + * @package StatusNet + * @author Zach Copley + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://status.net/ + * @see ApiAction + */ + +class ApiSearchJSONAction extends ApiPrivateAuthAction +{ + var $query; + var $lang; + var $rpp; + var $page; + var $since_id; + var $limit; + var $geocode; + + /** + * Initialization. + * + * @param array $args Web and URL arguments + * + * @return boolean true if nothing goes wrong + */ + + function prepare($args) + { + common_debug("apisearchjson prepare()"); + + parent::prepare($args); + + $this->query = $this->trimmed('q'); + $this->lang = $this->trimmed('lang'); + $this->rpp = $this->trimmed('rpp'); + + if (!$this->rpp) { + $this->rpp = 15; + } + + if ($this->rpp > 100) { + $this->rpp = 100; + } + + $this->page = $this->trimmed('page'); + + if (!$this->page) { + $this->page = 1; + } + + $this->since_id = $this->trimmed('since_id'); + $this->geocode = $this->trimmed('geocode'); + + return true; + } + + /** + * Handle a request + * + * @param array $args Arguments from $_REQUEST + * + * @return void + */ + + function handle($args) + { + parent::handle($args); + $this->showResults(); + } + + /** + * Show search results + * + * @return void + */ + + function showResults() + { + + // TODO: Support search operators like from: and to:, boolean, etc. + + $notice = new Notice(); + + // lcase it for comparison + $q = strtolower($this->query); + + $search_engine = $notice->getSearchEngine('notice'); + $search_engine->set_sort_mode('chron'); + $search_engine->limit(($this->page - 1) * $this->rpp, $this->rpp + 1, true); + if (false === $search_engine->query($q)) { + $cnt = 0; + } else { + $cnt = $notice->find(); + } + + // TODO: since_id, lang, geocode + + $results = new JSONSearchResultsList($notice, $q, $this->rpp, $this->page); + + $this->initDocument('json'); + $results->show(); + $this->endDocument('json'); + } + + /** + * Do we need to write to the database? + * + * @return boolean true + */ + + function isReadOnly($args) + { + return true; + } +} diff --git a/actions/apitrends.php b/actions/apitrends.php new file mode 100644 index 000000000..5b74636c6 --- /dev/null +++ b/actions/apitrends.php @@ -0,0 +1,90 @@ +. + * + * @category Search + * @package StatusNet + * @author Zach Copley + * @copyright 2008-2010 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET') && !defined('LACONICA')) { + exit(1); +} + +require_once INSTALLDIR.'/lib/apiprivateauth.php'; + +/** + * Returns the top ten queries that are currently trending + * + * @category Search + * @package StatusNet + * @author Zach Copley + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://status.net/ + * + * @see ApiAction + */ + +class ApiTrendsAction extends ApiPrivateAuthAction +{ + + var $callback; + + /** + * Initialization. + * + * @param array $args Web and URL arguments + * + * @return boolean false if user doesn't exist + */ + function prepare($args) + { + parent::prepare($args); + return true; + } + + /** + * Handle a request + * + * @param array $args Arguments from $_REQUEST + * + * @return void + */ + + function handle($args) + { + parent::handle($args); + $this->showTrends(); + } + + /** + * Output the trends + * + * @return void + */ + function showTrends() + { + $this->serverError(_('API method under construction.'), 501); + } + +} \ No newline at end of file diff --git a/actions/twitapisearchatom.php b/actions/twitapisearchatom.php deleted file mode 100644 index 51e8a8881..000000000 --- a/actions/twitapisearchatom.php +++ /dev/null @@ -1,402 +0,0 @@ -. - * - * @category Search - * @package StatusNet - * @author Zach Copley - * @copyright 2008-2009 StatusNet, Inc. - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 - * @link http://status.net/ - */ - -if (!defined('STATUSNET') && !defined('LACONICA')) { - exit(1); -} - -/** - * Action for outputting search results in Twitter compatible Atom - * format. - * - * TODO: abstract Atom stuff into a ruseable base class like - * RSS10Action. - * - * @category Search - * @package StatusNet - * @author Zach Copley - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 - * @link http://status.net/ - * - * @see ApiAction - */ - -class TwitapisearchatomAction extends ApiAction -{ - - var $cnt; - var $query; - var $lang; - var $rpp; - var $page; - var $since_id; - var $geocode; - - /** - * Constructor - * - * Just wraps the Action constructor. - * - * @param string $output URI to output to, default = stdout - * @param boolean $indent Whether to indent output, default true - * - * @see Action::__construct - */ - - function __construct($output='php://output', $indent=null) - { - parent::__construct($output, $indent); - } - - /** - * Do we need to write to the database? - * - * @return boolean true - */ - - function isReadonly() - { - return true; - } - - /** - * Read arguments and initialize members - * - * @param array $args Arguments from $_REQUEST - * - * @return boolean success - * - */ - - function prepare($args) - { - parent::prepare($args); - - $this->query = $this->trimmed('q'); - $this->lang = $this->trimmed('lang'); - $this->rpp = $this->trimmed('rpp'); - - if (!$this->rpp) { - $this->rpp = 15; - } - - if ($this->rpp > 100) { - $this->rpp = 100; - } - - $this->page = $this->trimmed('page'); - - if (!$this->page) { - $this->page = 1; - } - - // TODO: Suppport since_id -- we need to tweak the backend - // Search classes to support it. - - $this->since_id = $this->trimmed('since_id'); - $this->geocode = $this->trimmed('geocode'); - - // TODO: Also, language and geocode - - return true; - } - - /** - * Handle a request - * - * @param array $args Arguments from $_REQUEST - * - * @return void - */ - - function handle($args) - { - parent::handle($args); - $this->showAtom(); - } - - /** - * Get the notices to output as results. This also sets some class - * attrs so we can use them to calculate pagination, and output - * since_id and max_id. - * - * @return array an array of Notice objects sorted in reverse chron - */ - - function getNotices() - { - // TODO: Support search operators like from: and to:, boolean, etc. - - $notices = array(); - $notice = new Notice(); - - // lcase it for comparison - $q = strtolower($this->query); - - $search_engine = $notice->getSearchEngine('notice'); - $search_engine->set_sort_mode('chron'); - $search_engine->limit(($this->page - 1) * $this->rpp, - $this->rpp + 1, true); - if (false === $search_engine->query($q)) { - $this->cnt = 0; - } else { - $this->cnt = $notice->find(); - } - - $cnt = 0; - $this->max_id = 0; - - if ($this->cnt > 0) { - while ($notice->fetch()) { - - ++$cnt; - - if (!$this->max_id) { - $this->max_id = $notice->id; - } - - if ($cnt > $this->rpp) { - break; - } - - $notices[] = clone($notice); - } - } - - return $notices; - } - - /** - * Output search results as an Atom feed - * - * @return void - */ - - function showAtom() - { - $notices = $this->getNotices(); - - $this->initAtom(); - $this->showFeed(); - - foreach ($notices as $n) { - - $profile = $n->getProfile(); - - // Don't show notices from deleted users - - if (!empty($profile)) { - $this->showEntry($n); - } - } - - $this->endAtom(); - } - - /** - * Show feed specific Atom elements - * - * @return void - */ - - function showFeed() - { - // TODO: A9 OpenSearch stuff like search.twitter.com? - - $server = common_config('site', 'server'); - $sitename = common_config('site', 'name'); - - // XXX: Use xmlns:statusnet instead? - - $this->elementStart('feed', - array('xmlns' => 'http://www.w3.org/2005/Atom', - - // XXX: xmlns:twitter causes Atom validation to fail - // It's used for the source attr on notices - - 'xmlns:twitter' => 'http://api.twitter.com/', - 'xml:lang' => 'en-US')); // XXX Other locales ? - - $taguribase = TagURI::base(); - $this->element('id', null, "tag:$taguribase:search/$server"); - - $site_uri = common_path(false); - - $search_uri = $site_uri . 'api/search.atom?q=' . urlencode($this->query); - - if ($this->rpp != 15) { - $search_uri .= '&rpp=' . $this->rpp; - } - - // FIXME: this alternate link is not quite right because our - // web-based notice search doesn't support a rpp (responses per - // page) param yet - - $this->element('link', array('type' => 'text/html', - 'rel' => 'alternate', - 'href' => $site_uri . 'search/notice?q=' . - urlencode($this->query))); - - // self link - - $self_uri = $search_uri; - $self_uri .= ($this->page > 1) ? '&page=' . $this->page : ''; - - $this->element('link', array('type' => 'application/atom+xml', - 'rel' => 'self', - 'href' => $self_uri)); - - $this->element('title', null, "$this->query - $sitename Search"); - $this->element('updated', null, common_date_iso8601('now')); - - // XXX: The below "rel" links are not valid Atom, but it's what - // Twitter does... - - // refresh link - - $refresh_uri = $search_uri . "&since_id=" . $this->max_id; - - $this->element('link', array('type' => 'application/atom+xml', - 'rel' => 'refresh', - 'href' => $refresh_uri)); - - // pagination links - - if ($this->cnt > $this->rpp) { - - $next_uri = $search_uri . "&max_id=" . $this->max_id . - '&page=' . ($this->page + 1); - - $this->element('link', array('type' => 'application/atom+xml', - 'rel' => 'next', - 'href' => $next_uri)); - } - - if ($this->page > 1) { - - $previous_uri = $search_uri . "&max_id=" . $this->max_id . - '&page=' . ($this->page - 1); - - $this->element('link', array('type' => 'application/atom+xml', - 'rel' => 'previous', - 'href' => $previous_uri)); - } - - } - - /** - * Build an Atom entry similar to search.twitter.com's based on - * a given notice - * - * @param Notice $notice the notice to use - * - * @return void - */ - - function showEntry($notice) - { - $server = common_config('site', 'server'); - $profile = $notice->getProfile(); - $nurl = common_local_url('shownotice', array('notice' => $notice->id)); - - $this->elementStart('entry'); - - $taguribase = TagURI::base(); - - $this->element('id', null, "tag:$taguribase:$notice->id"); - $this->element('published', null, common_date_w3dtf($notice->created)); - $this->element('link', array('type' => 'text/html', - 'rel' => 'alternate', - 'href' => $nurl)); - $this->element('title', null, common_xml_safe_str(trim($notice->content))); - $this->element('content', array('type' => 'html'), $notice->rendered); - $this->element('updated', null, common_date_w3dtf($notice->created)); - $this->element('link', array('type' => 'image/png', - // XXX: Twitter uses rel="image" (not valid) - 'rel' => 'related', - 'href' => $profile->avatarUrl())); - - // @todo: Here is where we'd put in a link to an atom feed for threads - - $source = null; - - $ns = $notice->getSource(); - if ($ns) { - if (!empty($ns->name) && !empty($ns->url)) { - $source = '' - . htmlspecialchars($ns->name) - . ''; - } else { - $source = $ns->code; - } - } - - $this->element("twitter:source", null, $source); - - $this->elementStart('author'); - - $name = $profile->nickname; - - if ($profile->fullname) { - $name .= ' (' . $profile->fullname . ')'; - } - - $this->element('name', null, $name); - $this->element('uri', null, common_profile_uri($profile)); - $this->elementEnd('author'); - - $this->elementEnd('entry'); - } - - /** - * Initialize the Atom output, send headers - * - * @return void - */ - - function initAtom() - { - header('Content-Type: application/atom+xml; charset=utf-8'); - $this->startXml(); - } - - /** - * End the Atom feed - * - * @return void - */ - - function endAtom() - { - $this->elementEnd('feed'); - } - -} diff --git a/actions/twitapisearchjson.php b/actions/twitapisearchjson.php deleted file mode 100644 index b5c006aa7..000000000 --- a/actions/twitapisearchjson.php +++ /dev/null @@ -1,151 +0,0 @@ -. - * - * @category Search - * @package StatusNet - * @author Zach Copley - * @copyright 2008-2009 StatusNet, Inc. - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 - * @link http://status.net/ - */ - -if (!defined('STATUSNET') && !defined('LACONICA')) { - exit(1); -} - -require_once INSTALLDIR.'/lib/jsonsearchresultslist.php'; - -/** - * Action handler for Twitter-compatible API search - * - * @category Search - * @package StatusNet - * @author Zach Copley - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 - * @link http://status.net/ - * @see ApiAction - */ - -class TwitapisearchjsonAction extends ApiAction -{ - var $query; - var $lang; - var $rpp; - var $page; - var $since_id; - var $limit; - var $geocode; - - /** - * Initialization. - * - * @param array $args Web and URL arguments - * - * @return boolean true if nothing goes wrong - */ - - function prepare($args) - { - parent::prepare($args); - - $this->query = $this->trimmed('q'); - $this->lang = $this->trimmed('lang'); - $this->rpp = $this->trimmed('rpp'); - - if (!$this->rpp) { - $this->rpp = 15; - } - - if ($this->rpp > 100) { - $this->rpp = 100; - } - - $this->page = $this->trimmed('page'); - - if (!$this->page) { - $this->page = 1; - } - - $this->since_id = $this->trimmed('since_id'); - $this->geocode = $this->trimmed('geocode'); - - return true; - } - - /** - * Handle a request - * - * @param array $args Arguments from $_REQUEST - * - * @return void - */ - - function handle($args) - { - parent::handle($args); - $this->showResults(); - } - - /** - * Show search results - * - * @return void - */ - - function showResults() - { - - // TODO: Support search operators like from: and to:, boolean, etc. - - $notice = new Notice(); - - // lcase it for comparison - $q = strtolower($this->query); - - $search_engine = $notice->getSearchEngine('notice'); - $search_engine->set_sort_mode('chron'); - $search_engine->limit(($this->page - 1) * $this->rpp, $this->rpp + 1, true); - if (false === $search_engine->query($q)) { - $cnt = 0; - } else { - $cnt = $notice->find(); - } - - // TODO: since_id, lang, geocode - - $results = new JSONSearchResultsList($notice, $q, $this->rpp, $this->page); - - $this->initDocument('json'); - $results->show(); - $this->endDocument('json'); - } - - /** - * Do we need to write to the database? - * - * @return boolean true - */ - - function isReadOnly($args) - { - return true; - } -} diff --git a/actions/twitapitrends.php b/actions/twitapitrends.php deleted file mode 100644 index 5a04569a2..000000000 --- a/actions/twitapitrends.php +++ /dev/null @@ -1,88 +0,0 @@ -. - * - * @category Search - * @package StatusNet - * @author Zach Copley - * @copyright 2008-2009 StatusNet, Inc. - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 - * @link http://status.net/ - */ - -if (!defined('STATUSNET') && !defined('LACONICA')) { - exit(1); -} - -/** - * Returns the top ten queries that are currently trending - * - * @category Search - * @package StatusNet - * @author Zach Copley - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 - * @link http://status.net/ - * - * @see ApiAction - */ - -class TwitapitrendsAction extends ApiAction -{ - - var $callback; - - /** - * Initialization. - * - * @param array $args Web and URL arguments - * - * @return boolean false if user doesn't exist - */ - function prepare($args) - { - parent::prepare($args); - return true; - } - - /** - * Handle a request - * - * @param array $args Arguments from $_REQUEST - * - * @return void - */ - - function handle($args) - { - parent::handle($args); - $this->showTrends(); - } - - /** - * Output the trends - * - * @return void - */ - function showTrends() - { - $this->serverError(_('API method under construction.'), $code = 501); - } - -} \ No newline at end of file diff --git a/lib/router.php b/lib/router.php index fec229c9b..7e1e6a2a4 100644 --- a/lib/router.php +++ b/lib/router.php @@ -667,9 +667,9 @@ class Router ); // search - $m->connect('api/search.atom', array('action' => 'twitapisearchatom')); - $m->connect('api/search.json', array('action' => 'twitapisearchjson')); - $m->connect('api/trends.json', array('action' => 'twitapitrends')); + $m->connect('api/search.atom', array('action' => 'ApiSearchAtom')); + $m->connect('api/search.json', array('action' => 'ApiSearchJSON')); + $m->connect('api/trends.json', array('action' => 'ApiTrends')); $m->connect('api/oauth/request_token', array('action' => 'apioauthrequesttoken')); -- cgit v1.2.3-54-g00ecf