OStatus: moving parts of profile processing to Activity from feedmunger. Pausing before refactoring DB schema a bit to clean up feed vs person vs group info

This commit is contained in:
Brion Vibber 2010-02-17 01:49:49 +00:00
parent 4a139d1cc8
commit 454d0b5738
2 changed files with 175 additions and 18 deletions

View File

@ -218,10 +218,6 @@ class Ostatus_profile extends Memcached_DataObject
$profile->query('BEGIN');
// Awful hack! Awful hack!
$profile->verify = common_good_rand(16);
$profile->secret = common_good_rand(32);
try {
$local = $munger->profile();
@ -423,7 +419,10 @@ class Ostatus_profile extends Memcached_DataObject
protected function doSubscribe($mode)
{
$orig = clone($this);
$this->verify_token = md5(mt_rand() . ':' . $this->feeduri);
$this->verify_token = common_good_rand(16);
if ($mode == 'subscribe') {
$this->secret = common_good_rand(32);
}
$this->sub_state = $mode;
$this->update($orig);
unset($orig);
@ -701,18 +700,19 @@ class Ostatus_profile extends Memcached_DataObject
*/
protected function processPost($activity)
{
// @fixme pull profile reference from actor for group feeds
$actor = $this;
$localProfile = $actor->localProfile();
if (empty($localProfile)) {
common_log(LOG_INFO, "OStatus: ignoring post with invalid author");
return;
}
if (empty($activity->object)) {
// This shouldn't happen!
common_log(LOG_INFO, "OStatus: ignoring post with missing post object.");
return;
if ($this->isGroup()) {
// @fixme validate these profiles in some way!
$oprofile = $this->ensureActorProfile($activity);
} else {
$actorUri = $this->getActorProfileURI($activity);
if ($actorUri == $this->homeuri) {
// @fixme check if profile info has changed and update it
} else {
// @fixme drop or reject the messages once we've got the canonical profile URI recorded sanely
common_log(LOG_INFO, "OStatus: Warning: non-group post with unexpected author: $actorUri expected $this->homeuri");
//return;
}
$oprofile = $this;
}
if ($activity->object->link) {
@ -749,7 +749,7 @@ class Ostatus_profile extends Memcached_DataObject
// @fixme save detailed ostatus source info
// @fixme ensure that groups get handled correctly
$saved = Notice::saveNew($localProfile->id,
$saved = Notice::saveNew($oprofile->localProfile()->id,
$content,
'ostatus',
$params);
@ -784,4 +784,153 @@ class Ostatus_profile extends Memcached_DataObject
return false;
}
/**
* Get an appropriate avatar image source URL, if available.
*
* @param ActivityObject $actor
* @param DOMElement $feed
* @return string
*/
function getAvatar($actor, $feed)
{
$url = '';
$icon = '';
if ($actor->avatar) {
$url = trim($actor->avatar);
}
if (!$url) {
// Check <atom:logo> and <atom:icon> on the feed
$els = $feed->childNodes();
if ($els && $els->length) {
for ($i = 0; $i < $els->length; $i++) {
$el = $els->item($i);
if ($el->namespaceURI == Activity::ATOM) {
if (empty($url) && $el->localName == 'logo') {
$url = trim($el->textContent);
break;
}
if (empty($icon) && $el->localName == 'icon') {
// Use as a fallback
$icon = trim($el->textContent);
}
}
}
}
if ($icon && !$url) {
$url = $icon;
}
}
if ($url) {
$opts = array('allowed_schemes' => array('http', 'https'));
if (Validate::uri($url, $opts)) {
return $url;
}
}
return common_path('plugins/OStatus/images/96px-Feed-icon.svg.png');
}
/**
* @fixme move off of ostatus_profile or static?
*/
function ensureActorProfile($activity)
{
$profile = $this->getActorProfile($activity);
if (!$profile) {
$profile = $this->createActorProfile($activity);
}
return $profile;
}
/**
* @param Activity $activity
* @return mixed matching Ostatus_profile or false if none known
*/
function getActorProfile($activity)
{
$homeuri = $this->getActorProfileURI($activity);
return Ostatus_profile::staticGet('homeuri', $homeuri);
}
/**
* @param Activity $activity
* @return string
* @throws ServerException
*/
function getActorProfileURI($activity)
{
$opts = array('allowed_schemes' => array('http', 'https'));
$actor = $activity->actor;
if ($actor->id && Validate::uri($actor->id, $opts)) {
return $actor->id;
}
if ($actor->link && Validate::uri($actor->link, $opts)) {
return $actor->link;
}
throw new ServerException("No author ID URI found");
}
/**
*
*/
function createActorProfile($activity)
{
$actor = $activity->actor();
$homeuri = $this->getActivityProfileURI($activity);
$nickname = $this->getAuthorNick($activity);
$avatar = $this->getAvatar($actor, $feed);
$profile = new Profile();
$profile->nickname = $nickname;
$profile->fullname = $actor->displayName;
$profile->homepage = $actor->link; // @fixme
$profile->profileurl = $homeuri;
// @fixme bio
// @fixme tags/categories
// @fixme location?
// @todo tags from categories
// @todo lat/lon/location?
$ok = $profile->insert();
if ($ok) {
$this->updateAvatar($profile, $avatar);
} else {
throw new ServerException("Can't save local profile");
}
// @fixme either need to do feed discovery here
// or need to split out some of the feed stuff
// so we can leave it empty until later.
$oprofile = new Ostatus_profile();
$oprofile->homeuri = $homeuri;
$oprofile->profile_id = $profile->id;
$ok = $oprofile->insert();
if ($ok) {
return $oprofile;
} else {
throw new ServerException("Can't save OStatus profile");
}
}
/**
* @fixme move this into Activity?
* @param Activity $activity
* @return string
*/
function getAuthorNick($activity)
{
// @fixme not technically part of the actor?
foreach (array($activity->entry, $activity->feed) as $source) {
$author = ActivityUtil::child($source, 'author', Activity::ATOM);
if ($author) {
$name = ActivityUtil::child($author, 'name', Activity::ATOM);
if ($name) {
return trim($name->textContent);
}
}
}
return false;
}
}

View File

@ -247,6 +247,14 @@ class ActivityObject
// XXX: grab PoCo stuff
}
// Some per-type attributes...
if ($this->type == self::PERSON || $this->type == self::GROUP) {
$this->displayName = $this->title;
// @fixme we may have multiple avatars with different resolutions specified
$this->avatar = ActivityUtils::getLink($element, 'avatar');
}
}
private function _childContent($element, $tag, $namespace=ActivityUtils::ATOM)