forked from GNUsocial/gnu-social
		
	Twitter-compatible API:
- Filled in favorites tags in statuses - Filled in more tags in user/show, including undocumented features - Better error handling and more consistent error messages - Code clean-up and refactoring - Removed huge obnoxious comments darcs-hash:20081017023638-462f3-27b5d2709e423c616723d4bcfbc9d7d30a4ad161.gz
This commit is contained in:
		| @@ -40,20 +40,20 @@ class ApiAction extends Action { | ||||
| 			$this->api_method = $method; | ||||
| 			$this->content_type = strtolower($cmdext[1]); | ||||
| 		} else { | ||||
| 			#content type will be an extension on the method | ||||
| 			 | ||||
| 			# Requested format / content-type will be an extension on the method | ||||
| 			$cmdext = explode('.', $method); | ||||
| 			$this->api_method = $cmdext[0]; | ||||
| 			$this->content_type = strtolower($cmdext[1]); | ||||
| 		} | ||||
|  | ||||
| 		# XXX Maybe check to see if the command actually exists first? | ||||
| 		if($this->requires_auth()) { | ||||
| 			if (!isset($_SERVER['PHP_AUTH_USER'])) { | ||||
|  | ||||
| 				# This header makes basic auth go | ||||
| 				header('WWW-Authenticate: Basic realm="Laconica API"'); | ||||
|  | ||||
| 				# if the user hits cancel -- bam! | ||||
| 				# If the user hits cancel -- bam! | ||||
| 				$this->show_basic_auth_error(); | ||||
| 			} else { | ||||
| 				$nickname = $_SERVER['PHP_AUTH_USER']; | ||||
| @@ -69,6 +69,16 @@ class ApiAction extends Action { | ||||
| 				} | ||||
| 			} | ||||
| 		} else { | ||||
|  | ||||
| 			# Caller might give us a username even if not required | ||||
| 			if (isset($_SERVER['PHP_AUTH_USER'])) { | ||||
| 				$user = User::staticGet('nickname', $_SERVER['PHP_AUTH_USER']);	 | ||||
| 				if ($user) { | ||||
| 					$this->user = $user; | ||||
| 				} | ||||
| 				# Twitter doesn't throw an error if the user isn't found | ||||
| 			} | ||||
| 			 | ||||
| 			$this->process_command(); | ||||
| 		} | ||||
| 	} | ||||
| @@ -76,19 +86,21 @@ class ApiAction extends Action { | ||||
| 	function process_command() { | ||||
| 		$action = "twitapi$this->api_action"; | ||||
| 		$actionfile = INSTALLDIR."/actions/$action.php"; | ||||
|  | ||||
| 		if (file_exists($actionfile)) { | ||||
| 			require_once($actionfile); | ||||
| 			$action_class = ucfirst($action)."Action"; | ||||
| 			$action_obj = new $action_class(); | ||||
|  | ||||
| 			if (method_exists($action_obj, $this->api_method)) { | ||||
|  | ||||
| 				$apidata = array(	'content-type' => $this->content_type, | ||||
| 									'api_method' => $this->api_method, | ||||
| 									'api_arg' => $this->api_arg, | ||||
| 									'user' => $this->user); | ||||
|  | ||||
| 				call_user_func(array($action_obj, $this->api_method), $_REQUEST, $apidata); | ||||
| 			} else { | ||||
| 				common_user_error("API method not found!", $code=404); | ||||
| 			} | ||||
| 		} else { | ||||
| 			common_user_error("API method not found!", $code=404); | ||||
| @@ -126,10 +138,26 @@ class ApiAction extends Action { | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	function show_basic_auth_error() { | ||||
| 	function show_basic_auth_error() {	 | ||||
| 	  	header('HTTP/1.1 401 Unauthorized'); | ||||
| 		header('Content-type: text/plain'); | ||||
| 	   	print("Could not authenticate you."); # exactly what Twitter says - no \n | ||||
| 	   	$msg = 'Could not authenticate you.'; | ||||
| 	 | ||||
| 		if ($this->content_type == 'xml') { | ||||
| 			header('Content-Type: application/xml; charset=utf-8'); | ||||
| 			common_start_xml(); | ||||
| 			common_element_start('hash'); | ||||
| 			common_element('error', NULL, $msg); | ||||
| 			common_element('request', NULL, $_SERVER['REQUEST_URI']); | ||||
| 			common_element_end('hash'); | ||||
| 			common_end_xml(); | ||||
| 		} else if ($this->content_type == 'json')  { | ||||
| 			header('Content-Type: application/json; charset=utf-8');			 | ||||
| 			$error_array = array('error' => $msg, 'request' => $_SERVER['REQUEST_URI']); | ||||
| 			print(json_encode($error_array)); | ||||
| 		} else { | ||||
| 			header('Content-type: text/plain'); | ||||
| 			print "$msg\n"; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -39,27 +39,12 @@ class TwitapifavoritesAction extends TwitterapiAction { | ||||
| 	function favorites($args, $apidata) { | ||||
| 		parent::handle($args); | ||||
|  | ||||
| 		$user = null; | ||||
|  | ||||
| 		// function was called with an argument /favorites/api_arg.format | ||||
| 		if (isset($apidata['api_arg'])) { | ||||
|  | ||||
| 			if (is_numeric($apidata['api_arg'])) { | ||||
| 				$user = User::staticGet($apidata['api_arg']); | ||||
| 			} else { | ||||
| 				$nickname = common_canonical_nickname($apidata['api_arg']); | ||||
| 				$user = User::staticGet('nickname', $nickname); | ||||
| 			} | ||||
| 		} else { | ||||
|  | ||||
| 			// if no user was specified, then we'll use the authenticated user | ||||
| 			$user = $apidata['user']; | ||||
| 		} | ||||
| 		$this->auth_user = $apidata['user']; | ||||
| 		$user = $this->get_user($apidata['api_arg'], $apidata); | ||||
|  | ||||
| 		if (!$user) { | ||||
| 			// Set the user to be the auth user if asked-for can't be found | ||||
| 			// honestly! This is what Twitter does, I swear --Zach | ||||
| 			$user = $apidata['user']; | ||||
| 			$this->client_error('Not Found', 404, $apidata['content-type']); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		$profile = $user->getProfile(); | ||||
| @@ -116,11 +101,6 @@ class TwitapifavoritesAction extends TwitterapiAction { | ||||
| 	function create($args, $apidata) { | ||||
| 		parent::handle($args); | ||||
|  | ||||
| 		if (!in_array($apidata['content-type'], array('xml', 'json'))) { | ||||
| 			common_user_error(_('API method not found!'), $code = 404); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		// Check for RESTfulness | ||||
| 		if (!in_array($_SERVER['REQUEST_METHOD'], array('POST', 'DELETE'))) { | ||||
| 			// XXX: Twitter just prints the err msg, no XML / JSON. | ||||
| @@ -128,7 +108,13 @@ class TwitapifavoritesAction extends TwitterapiAction { | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		$user = $apidata['user']; | ||||
| 		if (!in_array($apidata['content-type'], array('xml', 'json'))) { | ||||
| 			common_user_error(_('API method not found!'), $code = 404); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		$this->auth_user = $apidata['user']; | ||||
| 		$user = $this->auth_user; | ||||
| 		$notice_id = $apidata['api_arg']; | ||||
| 		$notice = Notice::staticGet($notice_id); | ||||
|  | ||||
|   | ||||
| @@ -89,18 +89,6 @@ class TwitapifriendshipsAction extends TwitterapiAction { | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	//destroy | ||||
| 	// | ||||
| 	//Discontinues friendship with the user specified in the ID parameter as the authenticating user.  Returns the un-friended user in the requested format when successful.  Returns a string describing the failure condition when unsuccessful. | ||||
| 	// | ||||
| 	//URL: http://twitter.com/friendships/destroy/id.format | ||||
| 	// | ||||
| 	//Formats: xml, json | ||||
| 	// | ||||
| 	//Parameters: | ||||
| 	// | ||||
| 	//* id.  Required.  The ID or screen name of the user with whom to discontinue friendship.  Ex: http://twitter.com/friendships/destroy/12345.json or http://twitter.com/friendships/destroy/bob.xml | ||||
|  | ||||
| 	function destroy($args, $apidata) { | ||||
| 		parent::handle($args); | ||||
|  | ||||
| @@ -136,19 +124,6 @@ class TwitapifriendshipsAction extends TwitterapiAction { | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	//	Tests if a friendship exists between two users. | ||||
| 	// | ||||
| 	// | ||||
| 	//	  URL: http://twitter.com/friendships/exists.format | ||||
| 	// | ||||
| 	//	Formats: xml, json, none | ||||
| 	// | ||||
| 	//	  Parameters: | ||||
| 	// | ||||
| 	//	    * user_a.  Required.  The ID or screen_name of the first user to test friendship for. | ||||
| 	//	      * user_b.  Required.  The ID or screen_name of the second user to test friendship for. | ||||
| 	//	  * Ex: http://twitter.com/friendships/exists.xml?user_a=alice&user_b=bob | ||||
|  | ||||
| 	function exists($args, $apidata) { | ||||
| 		parent::handle($args); | ||||
|  | ||||
|   | ||||
| @@ -21,10 +21,6 @@ if (!defined('LACONICA')) { exit(1); } | ||||
|  | ||||
| require_once(INSTALLDIR.'/lib/twitterapi.php'); | ||||
|  | ||||
| /* XXX: Please don't freak out about all the ugly comments in this file. | ||||
|  * They are mostly in here for reference while I work on the | ||||
|  * API. I'll fix things up later to make them look better later. -- Zach | ||||
|  */ | ||||
| class TwitapistatusesAction extends TwitterapiAction { | ||||
|  | ||||
| 	function is_readonly() { | ||||
| @@ -100,26 +96,6 @@ class TwitapistatusesAction extends TwitterapiAction { | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	/* | ||||
| 	Returns the 20 most recent statuses posted by the authenticating user and that user's friends. | ||||
| 	This is the equivalent of /home on the Web. | ||||
|  | ||||
| 	URL: http://server/api/statuses/friends_timeline.format | ||||
|  | ||||
| 	Parameters: | ||||
|  | ||||
| 	    * since.  Optional.  Narrows the returned results to just those statuses created after the specified | ||||
| 			HTTP-formatted date.  The same behavior is available by setting an If-Modified-Since header in | ||||
| 			your HTTP request. | ||||
| 			Ex: http://server/api/statuses/friends_timeline.rss?since=Tue%2C+27+Mar+2007+22%3A55%3A48+GMT | ||||
| 	    * since_id.  Optional.  Returns only statuses with an ID greater than (that is, more recent than) | ||||
| 			the specified ID.  Ex: http://server/api/statuses/friends_timeline.xml?since_id=12345 | ||||
| 	    * count.  Optional.  Specifies the number of statuses to retrieve. May not be greater than 200. | ||||
| 	  		Ex: http://server/api/statuses/friends_timeline.xml?count=5 | ||||
| 	    * page. Optional. Ex: http://server/api/statuses/friends_timeline.rss?page=3 | ||||
|  | ||||
| 	Formats: xml, json, rss, atom | ||||
| 	*/ | ||||
| 	function friends_timeline($args, $apidata) { | ||||
| 		parent::handle($args); | ||||
|  | ||||
| @@ -141,19 +117,21 @@ class TwitapistatusesAction extends TwitterapiAction { | ||||
|             $since_id = 0; | ||||
|         } | ||||
|  | ||||
| 		// NOTE: before_id is an extensions to Twitter API -- TB | ||||
| 		// NOTE: before_id is an extension to Twitter API -- TB | ||||
|         if (!$before_id) { | ||||
|             $before_id = 0; | ||||
|         } | ||||
|  | ||||
| 		$user = $this->get_user($id, $apidata); | ||||
| 		$this->auth_user = $user; | ||||
|  | ||||
| 		$profile = $user->getProfile(); | ||||
|  | ||||
| 		$sitename = common_config('site', 'name'); | ||||
| 		$siteserver = common_config('site', 'server'); | ||||
|  | ||||
| 		$title = sprintf(_("%s and friends"), $user->nickname); | ||||
| 		$id = "tag:$siteserver:friends:".$user->id; | ||||
| 		$id = "tag:$siteserver:friends:" . $user->id; | ||||
| 		$link = common_local_url('all', array('nickname' => $user->nickname)); | ||||
| 		$subtitle = sprintf(_('Updates from %1$s and friends on %2$s!'), $user->nickname, $sitename); | ||||
|  | ||||
| @@ -178,55 +156,15 @@ class TwitapistatusesAction extends TwitterapiAction { | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	/* | ||||
| 		Returns the 20 most recent statuses posted from the authenticating user. It's also possible to | ||||
|         request another user's timeline via the id parameter below. This is the equivalent of the Web | ||||
|         /archive page for your own user, or the profile page for a third party. | ||||
|  | ||||
| 		URL: http://server/api/statuses/user_timeline.format | ||||
|  | ||||
| 		Formats: xml, json, rss, atom | ||||
|  | ||||
| 		Parameters: | ||||
|  | ||||
| 		    * id. Optional. Specifies the ID or screen name of the user for whom to return the | ||||
|             friends_timeline. Ex: http://server/api/statuses/user_timeline/12345.xml or | ||||
|             http://server/api/statuses/user_timeline/bob.json. | ||||
| 			* count. Optional. Specifies the number of | ||||
|             statuses to retrieve. May not be greater than 200. Ex: | ||||
|             http://server/api/statuses/user_timeline.xml?count=5 | ||||
| 			* since. Optional. Narrows the returned | ||||
|             results to just those statuses created after the specified HTTP-formatted date. The same | ||||
|             behavior is available by setting an If-Modified-Since header in your HTTP request. Ex: | ||||
|             http://server/api/statuses/user_timeline.rss?since=Tue%2C+27+Mar+2007+22%3A55%3A48+GMT | ||||
| 			* since_id. Optional. Returns only statuses with an ID greater than (that is, more recent than) | ||||
|             the specified ID. Ex: http://server/api/statuses/user_timeline.xml?since_id=12345 * page. | ||||
|             Optional. Ex: http://server/api/statuses/friends_timeline.rss?page=3 | ||||
| 	*/ | ||||
| 	function user_timeline($args, $apidata) { | ||||
| 		parent::handle($args); | ||||
|  | ||||
| 		$user = null; | ||||
|  | ||||
| 		// function was called with an argument /statuses/user_timeline/api_arg.format | ||||
| 		if (isset($apidata['api_arg'])) { | ||||
|  | ||||
| 			if (is_numeric($apidata['api_arg'])) { | ||||
| 				$user = User::staticGet($apidata['api_arg']); | ||||
| 			} else { | ||||
| 				$nickname = common_canonical_nickname($apidata['api_arg']); | ||||
| 				$user = User::staticGet('nickname', $nickname); | ||||
| 			} | ||||
| 		} else { | ||||
|  | ||||
| 			// if no user was specified, then we'll use the authenticated user | ||||
| 			$user = $apidata['user']; | ||||
| 		} | ||||
| 		$this->auth_user = $apidata['user']; | ||||
| 		$user = $this->get_user($apidata['api_arg'], $apidata); | ||||
|  | ||||
| 		if (!$user) { | ||||
| 			// Set the user to be the auth user if asked-for can't be found | ||||
| 			// honestly! This is what Twitter does, I swear --Zach | ||||
| 			$user = $apidata['user']; | ||||
| 			$this->client_error('Not Found', 404, $apidata['content-type']); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		$profile = $user->getProfile(); | ||||
| @@ -304,7 +242,8 @@ class TwitapistatusesAction extends TwitterapiAction { | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		$user = $apidata['user']; | ||||
| 		$this->auth_user = $apidata['user']; | ||||
| 		$user = $this->auth_user; | ||||
| 		$status = $this->trimmed('status'); | ||||
| 		$source = $this->trimmed('source'); | ||||
| 		$in_reply_to_status_id = intval($this->trimmed('in_reply_to_status_id')); | ||||
| @@ -377,33 +316,18 @@ class TwitapistatusesAction extends TwitterapiAction { | ||||
| 		$this->show($args, $apidata); | ||||
| 	} | ||||
|  | ||||
| 	/* | ||||
| 		Returns the 20 most recent @replies (status updates prefixed with @username) for the authenticating user. | ||||
| 		URL: http://server/api/statuses/replies.format | ||||
|  | ||||
| 		Formats: xml, json, rss, atom | ||||
|  | ||||
|  		Parameters: | ||||
|  | ||||
|  		* page. Optional. Retrieves the 20 next most recent replies. Ex: http://server/api/statuses/replies.xml?page=3 | ||||
| 		* since. Optional. Narrows the returned results to just those replies created after the specified HTTP-formatted date. The | ||||
|         same behavior is available by setting an If-Modified-Since header in your HTTP request. Ex: | ||||
|         http://server/api/statuses/replies.xml?since=Tue%2C+27+Mar+2007+22%3A55%3A48+GMT | ||||
| 		* since_id. Optional. Returns only statuses with an ID greater than (that is, more recent than) the specified | ||||
| 		ID. Ex: http://server/api/statuses/replies.xml?since_id=12345 | ||||
| 	*/ | ||||
| 	function replies($args, $apidata) { | ||||
|  | ||||
| 		parent::handle($args); | ||||
|  | ||||
| 		$since = $this->arg('since'); | ||||
|  | ||||
| 		$count = $this->arg('count'); | ||||
| 		$page = $this->arg('page'); | ||||
|     	$since_id = $this->arg('since_id'); | ||||
|     	$before_id = $this->arg('before_id'); | ||||
|  | ||||
| 		$user = $apidata['user']; | ||||
| 		$this->auth_user = $apidata['user']; | ||||
| 		$user = $this->auth_user; | ||||
| 		$profile = $user->getProfile(); | ||||
|  | ||||
| 		$sitename = common_config('site', 'name'); | ||||
| @@ -426,7 +350,7 @@ class TwitapistatusesAction extends TwitterapiAction { | ||||
|             $since_id = 0; | ||||
|         } | ||||
|  | ||||
| 		// NOTE: before_id is an extensions to Twitter API -- TB | ||||
| 		// NOTE: before_id is an extension to Twitter API -- TB | ||||
|         if (!$before_id) { | ||||
|             $before_id = 0; | ||||
|         } | ||||
| @@ -464,6 +388,7 @@ class TwitapistatusesAction extends TwitterapiAction { | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		$this->auth_user = $apidata['user']; | ||||
| 		$notice_id = $apidata['api_arg']; | ||||
| 		$notice = Notice::staticGet($notice_id); | ||||
|  | ||||
| @@ -480,22 +405,6 @@ class TwitapistatusesAction extends TwitterapiAction { | ||||
|  | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	/* | ||||
| 		Destroys the status specified by the required ID parameter. The authenticating user must be | ||||
|         the author of the specified status. | ||||
|  | ||||
| 		 URL: http://server/api/statuses/destroy/id.format | ||||
|  | ||||
| 		 Formats: xml, json | ||||
|  | ||||
| 		 Parameters: | ||||
|  | ||||
| 		 * id. Required. The ID of the status to destroy. Ex: | ||||
|         	http://server/api/statuses/destroy/12345.json or | ||||
|         	http://server/api/statuses/destroy/23456.xml | ||||
|  | ||||
| 	*/ | ||||
| 	function destroy($args, $apidata) { | ||||
|  | ||||
| 		parent::handle($args); | ||||
| @@ -512,7 +421,8 @@ class TwitapistatusesAction extends TwitterapiAction { | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		$user = $apidata['user']; | ||||
| 		$this->auth_user = $apidata['user']; | ||||
| 		$user = $this->auth_user; | ||||
| 		$notice_id = $apidata['api_arg']; | ||||
| 		$notice = Notice::staticGet($notice_id); | ||||
|  | ||||
| @@ -539,51 +449,11 @@ class TwitapistatusesAction extends TwitterapiAction { | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	# User Methods | ||||
|  | ||||
| 	/* | ||||
| 		Returns up to 100 of the authenticating user's friends who have most recently updated, each with current status inline. | ||||
|         It's also possible to request another user's recent friends list via the id parameter below. | ||||
|  | ||||
| 		 URL: http://server/api/statuses/friends.format | ||||
|  | ||||
| 		 Formats: xml, json | ||||
|  | ||||
| 		 Parameters: | ||||
|  | ||||
| 		 * id. Optional. The ID or screen name of the user for whom to request a list of friends. Ex: | ||||
|         	http://server/api/statuses/friends/12345.json | ||||
| 			or | ||||
| 			http://server/api/statuses/friends/bob.xml | ||||
| 		 * page. Optional. Retrieves the next 100 friends. Ex: http://server/api/statuses/friends.xml?page=2 | ||||
| 		 * lite. Optional. Prevents the inline inclusion of current status. Must be set to a value of true. Ex: | ||||
|         	http://server/api/statuses/friends.xml?lite=true | ||||
| 		 * since. Optional. Narrows the returned results to just those friendships created after the specified | ||||
|   			HTTP-formatted date. The same behavior is available by setting an If-Modified-Since header in your HTTP | ||||
|   			request. Ex: http://server/api/statuses/friends.xml?since=Tue%2C+27+Mar+2007+22%3A55%3A48+GMT | ||||
| 	*/ | ||||
| 	function friends($args, $apidata) { | ||||
| 		parent::handle($args); | ||||
| 		return $this->subscriptions($apidata, 'subscribed', 'subscriber'); | ||||
| 	} | ||||
|  | ||||
| 	/* | ||||
| 		Returns the authenticating user's followers, each with current status inline. They are ordered by the | ||||
| 		order in which they joined Twitter (this is going to be changed). | ||||
|  | ||||
| 		URL: http://server/api/statuses/followers.format | ||||
| 		Formats: xml, json | ||||
|  | ||||
| 		Parameters: | ||||
|  | ||||
| 		    * id. Optional. The ID or screen name of the user for whom to request a list of followers. Ex: | ||||
|             	http://server/api/statuses/followers/12345.json | ||||
| 				or | ||||
| 				http://server/api/statuses/followers/bob.xml | ||||
| 		    * page. Optional. Retrieves the next 100 followers. Ex: http://server/api/statuses/followers.xml?page=2 | ||||
| 		    * lite. Optional. Prevents the inline inclusion of current status. Must be set to a value of true. | ||||
| 		 		Ex: http://server/api/statuses/followers.xml?lite=true | ||||
| 	*/ | ||||
| 	function followers($args, $apidata) { | ||||
| 		parent::handle($args); | ||||
|  | ||||
| @@ -592,11 +462,16 @@ class TwitapistatusesAction extends TwitterapiAction { | ||||
|  | ||||
| 	function subscriptions($apidata, $other_attr, $user_attr) { | ||||
|  | ||||
| 		$user = $this->get_subs_user($apidata); | ||||
|  | ||||
| 		# XXX: id | ||||
| 		# XXX: lite | ||||
|  | ||||
| 		$this->auth_user = $apidate['user']; | ||||
| 		$user = $this->get_user($apidata['api_arg'], $apidata); | ||||
|  | ||||
| 		if (!$user) { | ||||
| 			$this->client_error('Not Found', 404, $apidata['content-type']); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		$page = $this->trimmed('page'); | ||||
|  | ||||
| 		if (!$page || !is_numeric($page)) { | ||||
| @@ -632,32 +507,6 @@ class TwitapistatusesAction extends TwitterapiAction { | ||||
| 		$this->end_document($type); | ||||
| 	} | ||||
|  | ||||
| 	function get_subs_user($apidata) { | ||||
|  | ||||
| 		// function was called with an argument /statuses/user_timeline/api_arg.format | ||||
| 		if (isset($apidata['api_arg'])) { | ||||
|  | ||||
| 			if (is_numeric($apidata['api_arg'])) { | ||||
| 				$user = User::staticGet($apidata['api_arg']); | ||||
| 			} else { | ||||
| 				$nickname = common_canonical_nickname($apidata['api_arg']); | ||||
| 				$user = User::staticGet('nickname', $nickname); | ||||
| 			} | ||||
| 		} else { | ||||
|  | ||||
| 			// if no user was specified, then we'll use the authenticated user | ||||
| 			$user = $apidata['user']; | ||||
| 		} | ||||
|  | ||||
| 		if (!$user) { | ||||
| 			// Set the user to be the auth user if asked-for can't be found | ||||
| 			// honestly! This is what Twitter does, I swear --Zach | ||||
| 			$user = $apidata['user']; | ||||
| 		} | ||||
|  | ||||
| 		return $user; | ||||
| 	} | ||||
|  | ||||
| 	function show_profiles($profiles, $type) { | ||||
| 		switch ($type) { | ||||
| 		 case 'xml': | ||||
| @@ -679,27 +528,11 @@ class TwitapistatusesAction extends TwitterapiAction { | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/* | ||||
| 	Returns a list of the users currently featured on the site with their current statuses inline. | ||||
| 	URL: http://server/api/statuses/featured.format | ||||
|  | ||||
| 	Formats: xml, json | ||||
| 	*/ | ||||
| 	function featured($args, $apidata) { | ||||
| 		parent::handle($args); | ||||
| 		common_server_error(_('API method under construction.'), $code=501); | ||||
| 	} | ||||
|  | ||||
| 	function get_user($id, $apidata) { | ||||
| 		if (!$id) { | ||||
| 			return $apidata['user']; | ||||
| 		} else if (is_numeric($id)) { | ||||
| 			return User::staticGet($id); | ||||
| 		} else { | ||||
| 			return User::staticGet('nickname', $id); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	function supported($cmd) { | ||||
|  | ||||
| 		$cmdlist = array('MessageCommand', 'SubCommand', 'UnsubCommand', 'FavCommand', 'OnCommand', 'OffCommand'); | ||||
| @@ -712,4 +545,3 @@ class TwitapistatusesAction extends TwitterapiAction { | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -27,27 +27,6 @@ class TwitapiusersAction extends TwitterapiAction { | ||||
| 		return true; | ||||
| 	} | ||||
|  | ||||
| /* | ||||
| 	Returns extended information of a given user, specified by ID or | ||||
| 	screen name as per the required id parameter below.	 This information | ||||
| 	includes design settings, so third party developers can theme their | ||||
| 	widgets according to a given user's preferences. You must be properly | ||||
| 	authenticated to request the page of a protected user. | ||||
|  | ||||
| 	URL: http://twitter.com/users/show/id.format | ||||
|  | ||||
| 	Formats: xml, json | ||||
|  | ||||
| 	Parameters: | ||||
|  | ||||
| 	* id.  Required.  The ID or screen name of a user. | ||||
| 	Ex: http://twitter.com/users/show/12345.json or | ||||
| 	http://twitter.com/users/show/bob.xml | ||||
|  | ||||
| 	* email. Optional.	The email address of a user.  Ex: | ||||
| 	http://twitter.com/users/show.xml?email=test@example.com | ||||
|  | ||||
| */ | ||||
| 	function show($args, $apidata) { | ||||
| 		parent::handle($args); | ||||
|  | ||||
| @@ -56,28 +35,19 @@ class TwitapiusersAction extends TwitterapiAction { | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		$this->auth_user = $apidata['user']; | ||||
| 		$user = null; | ||||
| 		$email = $this->arg('email'); | ||||
|  | ||||
| 		if (isset($apidata['api_arg'])) { | ||||
| 			if (is_numeric($apidata['api_arg'])) { | ||||
| 				// by user id | ||||
| 				$user = User::staticGet($apidata['api_arg']); | ||||
| 			} else { | ||||
| 				// by nickname | ||||
| 				$nickname = common_canonical_nickname($apidata['api_arg']); | ||||
| 				$user = User::staticGet('nickname', $nickname); | ||||
| 			} | ||||
| 		} elseif ($email) { | ||||
| 			// or, find user by email address | ||||
| 			// XXX: The Twitter API spec say an id is *required*, but you can actually | ||||
| 			// pull up a user with just an email address. -- Zach | ||||
| 		if ($email) { | ||||
| 			$user = User::staticGet('email', $email); | ||||
| 		} elseif (isset($apidata['api_arg'])) { | ||||
| 			$user = $this->get_user($apidata['api_arg']); | ||||
| 		} | ||||
|  | ||||
| 		if (!$user) { | ||||
| 			// XXX: Twitter returns a random(?) user instead of throwing and err! -- Zach | ||||
| 			$this->client_error(_('User not found.'), 404, $apidata['content-type']); | ||||
| 			$this->client_error(_('Not found.'), 404, $apidata['content-type']); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| @@ -109,11 +79,34 @@ class TwitapiusersAction extends TwitterapiAction { | ||||
| 		$twitter_user['profile_text_color'] = ''; | ||||
| 		$twitter_user['profile_link_color'] = ''; | ||||
| 		$twitter_user['profile_sidebar_fill_color'] = ''; | ||||
| 		$twitter_user['favourites_count'] = 0; | ||||
| 		$twitter_user['utc_offset'] = ''; | ||||
| 		$twitter_user['time_zone'] = ''; | ||||
| 		$twitter_user['following'] = ''; | ||||
| 		$twitter_user['notifications'] = ''; | ||||
|  | ||||
| 		$faves = DB_DataObject::factory('fave'); | ||||
| 		$faves->user_id = $user->id; | ||||
| 		$faves_count = (int) $faves->count(); | ||||
| 		$twitter_user['favourites_count'] = $faves_count; | ||||
|  | ||||
| 		$timezone = 'UTC'; | ||||
|  | ||||
| 		if ($user->timezone) { | ||||
| 			$timezone = $user->timezone; | ||||
| 		} | ||||
|  | ||||
| 		$t = new DateTime; | ||||
| 		$t->setTimezone(new DateTimeZone($timezone)); | ||||
| 		$twitter_user['utc_offset'] = $t->format('Z'); | ||||
| 		$twitter_user['time_zone'] = $timezone; | ||||
|  | ||||
| 		if (isset($this->auth_user)) { | ||||
|  | ||||
| 			if ($this->auth_user->isSubscribed($profile)) { | ||||
| 				$twitter_user['following'] = 'true'; | ||||
| 			} else { | ||||
| 				$twitter_user['following'] = 'false'; | ||||
| 			} | ||||
|  | ||||
| 			// Not implemented yet | ||||
| 			$twitter_user['notifications'] = 'false'; | ||||
| 		} | ||||
|  | ||||
| 		if ($apidata['content-type'] == 'xml') { | ||||
| 			$this->init_document('xml'); | ||||
|   | ||||
| @@ -21,6 +21,8 @@ if (!defined('LACONICA')) { exit(1); } | ||||
|  | ||||
| class TwitterapiAction extends Action { | ||||
|  | ||||
| 	var $auth_user; | ||||
|  | ||||
| 	function handle($args) { | ||||
| 		parent::handle($args); | ||||
| 	} | ||||
| @@ -53,10 +55,11 @@ class TwitterapiAction extends Action { | ||||
| 		return $twitter_user; | ||||
| 	} | ||||
|  | ||||
| 	function twitter_status_array($notice, $get_user=true) { | ||||
| 	function twitter_status_array($notice, $include_user=true) { | ||||
|  | ||||
| 		$profile = $notice->getProfile(); | ||||
|  | ||||
| 		$twitter_status = array(); | ||||
|  | ||||
| 		$twitter_status['text'] = $notice->content; | ||||
| 		$twitter_status['truncated'] = 'false'; # Not possible on Laconica | ||||
| 		$twitter_status['created_at'] = $this->date_twitter($notice->created); | ||||
| @@ -64,12 +67,18 @@ class TwitterapiAction extends Action { | ||||
| 		$twitter_status['source'] = $this->source_link($notice->source); | ||||
| 		$twitter_status['id'] = intval($notice->id); | ||||
| 		$twitter_status['in_reply_to_user_id'] = ($notice->reply_to) ? $this->replier_by_reply(intval($notice->reply_to)) : NULL; | ||||
| 		$twitter_status['favorited'] = NULL; # XXX: Not implemented on Laconica yet. | ||||
| 		 | ||||
| 		if (isset($this->auth_user)) { | ||||
| 			common_debug("auth user set: " . $this->auth_user->nickname); | ||||
| 			$twitter_status['favorited'] = ($this->auth_user->hasFave($notice)) ? 'true' : 'false'; | ||||
| 		} else { | ||||
| 			common_debug("no auth user set"); | ||||
| 			$twitter_status['favorited'] = 'false'; | ||||
| 		} | ||||
|  | ||||
| 		if ($get_user) { | ||||
| 			$profile = $notice->getProfile(); | ||||
| 		if ($include_user) { | ||||
| 			# Don't get notice (recursive!) | ||||
| 			$twitter_user = $this->twitter_user_array($profile, false); | ||||
| 			$twitter_user = $this->twitter_user_array($profile, false, $user); | ||||
| 			$twitter_status['user'] = $twitter_user; | ||||
| 		} | ||||
|  | ||||
| @@ -364,7 +373,7 @@ class TwitterapiAction extends Action { | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	function init_document($type='xml') { | ||||
| 	function init_document($type='xml') {	 | ||||
| 		switch ($type) { | ||||
| 		 case 'xml': | ||||
| 			header('Content-Type: application/xml; charset=utf-8'); | ||||
| @@ -505,11 +514,14 @@ class TwitterapiAction extends Action { | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	function get_user($id) { | ||||
| 		if (is_numeric($id)) { | ||||
| 	function get_user($id, $apidata=NULL) { | ||||
| 		if (!$id) { | ||||
| 			return $apidata['user']; | ||||
| 		} else if (is_numeric($id)) { | ||||
| 			return User::staticGet($id); | ||||
| 		} else { | ||||
| 			return User::staticGet('nickname', $id); | ||||
| 			$nickname = common_canonical_nickname($id); | ||||
| 			return User::staticGet('nickname', $nickname); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user