diff --git a/actions/apimediaupload.php b/actions/apimediaupload.php new file mode 100644 index 0000000000..ec316edc8d --- /dev/null +++ b/actions/apimediaupload.php @@ -0,0 +1,141 @@ +. + * + * @category API + * @author Zach Copley + * @copyright 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')) { + exit(1); +} + +require_once INSTALLDIR . '/lib/apiauth.php'; +require_once INSTALLDIR . '/lib/mediafile.php'; + +/** + * Upload an image via the API. Returns a shortened URL for the image + * to the user. + * + * @category API + * @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/ + */ + +class ApiMediaUploadAction extends ApiAuthAction +{ + /** + * Handle the request + * + * Grab the file from the 'media' param, then store, and shorten + * + * @todo Upload throttle! + * + * @param array $args $_REQUEST data (unused) + * + * @return void + */ + + function handle($args) + { + parent::handle($args); + + if ($_SERVER['REQUEST_METHOD'] != 'POST') { + $this->clientError( + _('This method requires a POST.'), + 400, $this->format + ); + return; + } + + // Workaround for PHP returning empty $_POST and $_FILES when POST + // length > post_max_size in php.ini + + if (empty($_FILES) + && empty($_POST) + && ($_SERVER['CONTENT_LENGTH'] > 0) + ) { + $msg = _('The server was unable to handle that much POST ' . + 'data (%s bytes) due to its current configuration.'); + + $this->clientError(sprintf($msg, $_SERVER['CONTENT_LENGTH'])); + return; + } + + $upload = null; + + try { + $upload = MediaFile::fromUpload('media', $this->auth_user); + } catch (ClientException $ce) { + $this->clientError($ce->getMessage()); + return; + } + + if (isset($upload)) { + $this->showResponse($upload); + } else { + $this->clientError('Upload failed.'); + return; + } + } + + /** + * Show a Twitpic-like response with the ID of the media file + * and a (hopefully) shortened URL for it. + * + * @param File $upload the uploaded file + * + * @return void + */ + function showResponse($upload) + { + $this->initDocument(); + $this->elementStart('rsp', array('stat' => 'ok')); + $this->element('mediaid', null, $upload->fileRecord->id); + $this->element('mediaurl', null, $upload->shortUrl()); + $this->elementEnd('rsp'); + $this->endDocument(); + } + + /** + * Overrided clientError to show a more Twitpic-like error + * + * @param String $msg an error message + * + */ + function clientError($msg) + { + $this->initDocument(); + $this->elementStart('rsp', array('stat' => 'fail')); + + // @todo add in error code + $errAttr = array('msg' => $msg); + + $this->element('err', $errAttr, null); + $this->elementEnd('rsp'); + $this->endDocument(); + } + +} diff --git a/lib/router.php b/lib/router.php index 706120e0bf..a48ee875e1 100644 --- a/lib/router.php +++ b/lib/router.php @@ -628,6 +628,12 @@ class Router array('action' => 'ApiTimelineTag', 'format' => '(xmljson|rss|atom)')); + // media related + $m->connect( + 'api/statusnet/media/upload', + array('action' => 'ApiMediaUpload') + ); + // search $m->connect('api/search.atom', array('action' => 'twitapisearchatom')); $m->connect('api/search.json', array('action' => 'twitapisearchjson'));