Image file attachment support for Yammer import

This commit is contained in:
Brion Vibber 2010-09-21 17:08:40 -07:00
parent b18c7ee3eb
commit e357e13d69
4 changed files with 112 additions and 21 deletions

View File

@ -38,25 +38,34 @@ class SN_YammerClient
} }
/** /**
* Make an HTTP hit with OAuth headers and return the response body on success. * Make an HTTP GET request with OAuth headers and return an HTTPResponse
* with the returned body and codes.
* *
* @param string $path URL chunk for the API method * @param string $url
* @param array $params * @return HTTPResponse
* @return array
* *
* @throws Exception for HTTP error * @throws Exception on low-level network error
*/ */
protected function fetch($path, $params=array()) protected function httpGet($url)
{ {
$url = $this->apiBase . '/' . $path;
if ($params) {
$url .= '?' . http_build_query($params, null, '&');
}
$headers = array('Authorization: ' . $this->authHeader()); $headers = array('Authorization: ' . $this->authHeader());
$client = HTTPClient::start(); $client = HTTPClient::start();
$response = $client->get($url, $headers); return $client->get($url, $headers);
}
/**
* Make an HTTP GET request with OAuth headers and return the response body
* on success.
*
* @param string $url
* @return string
*
* @throws Exception on low-level network or HTTP error
*/
public function fetchUrl($url)
{
$response = $this->httpGet($url);
if ($response->isOk()) { if ($response->isOk()) {
return $response->getBody(); return $response->getBody();
} else { } else {
@ -64,6 +73,24 @@ class SN_YammerClient
} }
} }
/**
* Make an HTTP hit with OAuth headers and return the response body on success.
*
* @param string $path URL chunk for the API method
* @param array $params
* @return string
*
* @throws Exception on low-level network or HTTP error
*/
protected function fetchApi($path, $params=array())
{
$url = $this->apiBase . '/' . $path;
if ($params) {
$url .= '?' . http_build_query($params, null, '&');
}
return $this->fetchUrl($url);
}
/** /**
* Hit the main Yammer API point and decode returned JSON data. * Hit the main Yammer API point and decode returned JSON data.
* *
@ -75,7 +102,7 @@ class SN_YammerClient
*/ */
protected function api($method, $params=array()) protected function api($method, $params=array())
{ {
$body = $this->fetch("api/v1/$method.json", $params); $body = $this->fetchApi("api/v1/$method.json", $params);
$data = json_decode($body, true); $data = json_decode($body, true);
if (!$data) { if (!$data) {
throw new Exception("Invalid JSON response from Yammer API"); throw new Exception("Invalid JSON response from Yammer API");

View File

@ -11,7 +11,7 @@ require INSTALLDIR . "/scripts/commandline.inc";
// temp stuff // temp stuff
require 'yam-config.php'; require 'yam-config.php';
$yam = new SN_YammerClient($consumerKey, $consumerSecret, $token, $tokenSecret); $yam = new SN_YammerClient($consumerKey, $consumerSecret, $token, $tokenSecret);
$imp = new YammerImporter(); $imp = new YammerImporter($yam);
$data = $yam->messages(); $data = $yam->messages();
var_dump($data); var_dump($data);

View File

@ -11,7 +11,7 @@ require INSTALLDIR . "/scripts/commandline.inc";
// temp stuff // temp stuff
require 'yam-config.php'; require 'yam-config.php';
$yam = new SN_YammerClient($consumerKey, $consumerSecret, $token, $tokenSecret); $yam = new SN_YammerClient($consumerKey, $consumerSecret, $token, $tokenSecret);
$imp = new YammerImporter(); $imp = new YammerImporter($yam);
$data = $yam->messages(); $data = $yam->messages();
/* /*

View File

@ -25,11 +25,16 @@
*/ */
class YammerImporter class YammerImporter
{ {
protected $client;
protected $users=array(); protected $users=array();
protected $groups=array(); protected $groups=array();
protected $notices=array(); protected $notices=array();
function __construct(SN_YammerClient $client)
{
$this->client = $client;
}
/** /**
* Load or create an imported profile from Yammer data. * Load or create an imported profile from Yammer data.
* *
@ -95,17 +100,39 @@ class YammerImporter
if ($noticeId) { if ($noticeId) {
return Notice::staticGet('id', $noticeId); return Notice::staticGet('id', $noticeId);
} else { } else {
$notice = Notice::saveNew($data['profile'], $content = $data['content'];
$data['content'], $user = User::staticGet($data['profile']);
// Fetch file attachments and add the URLs...
$uploads = array();
foreach ($data['attachments'] as $url) {
try {
$upload = $this->saveAttachment($url, $user);
$content .= ' ' . $upload->shortUrl();
$uploads[] = $upload;
} catch (Exception $e) {
common_log(LOG_ERROR, "Error importing Yammer attachment: " . $e->getMessage());
}
}
// Here's the meat! Actually save the dang ol' notice.
$notice = Notice::saveNew($user->id,
$content,
$data['source'], $data['source'],
$data['options']); $data['options']);
// Save "likes" as favorites...
foreach ($data['faves'] as $nickname) { foreach ($data['faves'] as $nickname) {
$user = User::staticGet('nickname', $nickname); $user = User::staticGet('nickname', $nickname);
if ($user) { if ($user) {
Fave::addNew($user->getProfile(), $notice); Fave::addNew($user->getProfile(), $notice);
} }
} }
// @fixme attachments?
// And finally attach the upload records...
foreach ($uploads as $upload) {
$upload->attachToNotice($notice);
}
$this->recordImportedNotice($data['orig_id'], $notice->id); $this->recordImportedNotice($data['orig_id'], $notice->id);
return $notice; return $notice;
} }
@ -219,8 +246,14 @@ class YammerImporter
$faves[] = $liker['permalink']; $faves[] = $liker['permalink'];
} }
// Parse/save rendered text? $attachments = array();
// @todo attachments? foreach ($item['attachments'] as $attach) {
if ($attach['type'] == 'image') {
$attachments[] = $attach['image']['url'];
} else {
common_log(LOG_WARNING, "Unrecognized Yammer attachment type: " . $attach['type']);
}
}
return array('orig_id' => $origId, return array('orig_id' => $origId,
'orig_url' => $origUrl, 'orig_url' => $origUrl,
@ -228,7 +261,8 @@ class YammerImporter
'content' => $content, 'content' => $content,
'source' => $source, 'source' => $source,
'options' => $options, 'options' => $options,
'faves' => $faves); 'faves' => $faves,
'attachments' => $attachments);
} }
private function findImportedUser($origId) private function findImportedUser($origId)
@ -326,4 +360,34 @@ class YammerImporter
$dest->setOriginal($filename); $dest->setOriginal($filename);
} }
/**
* Fetch an attachment from Yammer and save it into our system.
* Unlike avatars, the attachment URLs are guarded by authentication,
* so we need to run the HTTP hit through our OAuth API client.
*
* @param string $url
* @param User $user
* @return MediaFile
*
* @throws Exception on low-level network or HTTP error
*/
private function saveAttachment($url, User $user)
{
// Fetch the attachment...
// WARNING: file must fit in memory here :(
$body = $this->client->fetchUrl($url);
// Save to a temporary file and shove it into our file-attachment space...
$temp = tmpfile();
fwrite($temp, $body);
try {
$upload = MediaFile::fromFileHandle($temp, $user);
fclose($temp);
return $upload;
} catch (Exception $e) {
fclose($temp);
throw $e;
}
}
} }