From bd68154772e80a98e9e5c96c6df8772ce3b2a84f Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Wed, 24 Feb 2010 23:28:41 -0500 Subject: Make user_group able to handle remote groups We add a local_group table to store data about local groups. It has the unique key for nickname, so /group/ looks up here. Updated DB data object classes and data files. --- classes/Local_group.php | 23 ++++++++++++++++++++ classes/User_group.php | 27 ++++++++++++----------- classes/statusnet.ini | 58 +++++++++++++++++++------------------------------ 3 files changed, 59 insertions(+), 49 deletions(-) create mode 100755 classes/Local_group.php mode change 100644 => 100755 classes/statusnet.ini (limited to 'classes') diff --git a/classes/Local_group.php b/classes/Local_group.php new file mode 100755 index 000000000..02663048f --- /dev/null +++ b/classes/Local_group.php @@ -0,0 +1,23 @@ + Date: Wed, 24 Feb 2010 23:30:14 -0500 Subject: fixup exe bits --- classes/Local_group.php | 0 classes/statusnet.ini | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 classes/Local_group.php mode change 100755 => 100644 classes/statusnet.ini (limited to 'classes') diff --git a/classes/Local_group.php b/classes/Local_group.php old mode 100755 new mode 100644 diff --git a/classes/statusnet.ini b/classes/statusnet.ini old mode 100755 new mode 100644 -- cgit v1.2.3-54-g00ecf From ddc3671b6aeb0b543d261251a1740a53469684c3 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Wed, 24 Feb 2010 23:32:20 -0500 Subject: recover user_openid tables, which got lost in generation --- classes/statusnet.ini | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'classes') diff --git a/classes/statusnet.ini b/classes/statusnet.ini index d483f4741..7444306f0 100644 --- a/classes/statusnet.ini +++ b/classes/statusnet.ini @@ -1,4 +1,3 @@ - [avatar] profile_id = 129 original = 17 @@ -606,6 +605,27 @@ uri = 2 [user_group__keys] id = N +[user_openid] +canonical = 130 +display = 130 +user_id = 129 +created = 142 +modified = 384 + +[user_openid__keys] +canonical = K +display = U + +[user_openid_trustroot] +trustroot = 130 +user_id = 129 +created = 142 +modified = 384 + +[user_openid__keys] +trustroot = K +user_id = K + [user_location_prefs] user_id = 129 share_location = 17 -- cgit v1.2.3-54-g00ecf From e6858d7203bd36923f6251968bede6f4b271bf84 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Thu, 25 Feb 2010 08:44:15 -0500 Subject: modify group actions so they use Local_group to look up by nickname --- actions/apigroupcreate.php | 8 +++-- actions/apigrouplistall.php | 10 +++--- actions/blockedfromgroup.php | 9 +++++- actions/editgroup.php | 14 +++++++-- actions/foafgroup.php | 17 ++++++++--- actions/groupdesignsettings.php | 5 ++- actions/grouplogo.php | 5 ++- actions/groupmembers.php | 9 +++++- actions/grouprss.php | 9 +++++- actions/groups.php | 18 ++++++----- actions/joingroup.php | 9 +++++- actions/leavegroup.php | 9 +++++- actions/newgroup.php | 7 +++-- actions/showgroup.php | 10 +++++- classes/Local_group.php | 29 ++++++++++++++++-- classes/User_group.php | 68 ++++++++++++++++++++++++----------------- lib/api.php | 21 +++++++++++-- 17 files changed, 190 insertions(+), 67 deletions(-) (limited to 'classes') diff --git a/actions/apigroupcreate.php b/actions/apigroupcreate.php index 028d76a78..145806356 100644 --- a/actions/apigroupcreate.php +++ b/actions/apigroupcreate.php @@ -123,7 +123,9 @@ class ApiGroupCreateAction extends ApiAuthAction 'description' => $this->description, 'location' => $this->location, 'aliases' => $this->aliases, - 'userid' => $this->user->id)); + 'userid' => $this->user->id, + 'local' => true)); + switch($this->format) { case 'xml': $this->showSingleXmlGroup($group); @@ -306,9 +308,9 @@ class ApiGroupCreateAction extends ApiAuthAction function groupNicknameExists($nickname) { - $group = User_group::staticGet('nickname', $nickname); + $local = Local_group::staticGet('nickname', $nickname); - if (!empty($group)) { + if (!empty($local)) { return true; } diff --git a/actions/apigrouplistall.php b/actions/apigrouplistall.php index d2ef2978a..e1b54a832 100644 --- a/actions/apigrouplistall.php +++ b/actions/apigrouplistall.php @@ -134,13 +134,13 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction function getGroups() { - $groups = array(); - - // XXX: Use the $page, $count, $max_id, $since_id, and $since parameters + $qry = 'SELECT user_group.* '. + 'from user_group join local_group on user_group.id = local_group.group_id '. + 'order by created desc '; $group = new User_group(); - $group->orderBy('created DESC'); - $group->find(); + + $group->query($qry); while ($group->fetch()) { $groups[] = clone($group); diff --git a/actions/blockedfromgroup.php b/actions/blockedfromgroup.php index 0b4caf5bf..a0598db27 100644 --- a/actions/blockedfromgroup.php +++ b/actions/blockedfromgroup.php @@ -74,7 +74,14 @@ class BlockedfromgroupAction extends GroupDesignAction return false; } - $this->group = User_group::staticGet('nickname', $nickname); + $local = Local_group::staticGet('nickname', $nickname); + + if (!$local) { + $this->clientError(_('No such group.'), 404); + return false; + } + + $this->group = User_group::staticGet('id', $local->group_id); if (!$this->group) { $this->clientError(_('No such group.'), 404); diff --git a/actions/editgroup.php b/actions/editgroup.php index ad0b6e185..bbbb7a0f4 100644 --- a/actions/editgroup.php +++ b/actions/editgroup.php @@ -86,10 +86,14 @@ class EditgroupAction extends GroupDesignAction } $groupid = $this->trimmed('groupid'); + if ($groupid) { $this->group = User_group::staticGet('id', $groupid); } else { - $this->group = User_group::staticGet('nickname', $nickname); + $local = Local_group::staticGet('nickname', $nickname); + if ($local) { + $this->group = User_group::staticGet('id', $local->group_id); + } } if (!$this->group) { @@ -259,6 +263,12 @@ class EditgroupAction extends GroupDesignAction $this->serverError(_('Could not create aliases.')); } + if ($nickname != $orig->nickname) { + common_log(LOG_INFO, "Saving local group info."); + $local = Local_group::staticGet('group_id', $this->group->id); + $local->setNickname($nickname); + } + $this->group->query('COMMIT'); if ($this->group->nickname != $orig->nickname) { @@ -272,7 +282,7 @@ class EditgroupAction extends GroupDesignAction function nicknameExists($nickname) { - $group = User_group::staticGet('nickname', $nickname); + $group = Local_group::staticGet('nickname', $nickname); if (!empty($group) && $group->id != $this->group->id) { diff --git a/actions/foafgroup.php b/actions/foafgroup.php index f5fd7fe88..ebdf1cee2 100644 --- a/actions/foafgroup.php +++ b/actions/foafgroup.php @@ -56,7 +56,14 @@ class FoafGroupAction extends Action return false; } - $this->group = User_group::staticGet('nickname', $this->nickname); + $local = Local_group::staticGet('nickname', $nickname); + + if (!$local) { + $this->clientError(_('No such group.'), 404); + return false; + } + + $this->group = User_group::staticGet('id', $local->group_id); if (!$this->group) { $this->clientError(_('No such group.'), 404); @@ -113,7 +120,7 @@ class FoafGroupAction extends Action if ($this->group->homepage_logo) { $this->element('depiction', array('rdf:resource' => $this->group->homepage_logo)); } - + $members = $this->group->getMembers(); $member_details = array(); while ($members->fetch()) { @@ -123,7 +130,7 @@ class FoafGroupAction extends Action ); $this->element('member', array('rdf:resource' => $member_uri)); } - + $admins = $this->group->getAdmins(); while ($admins->fetch()) { $admin_uri = common_local_url('userbyid', array('id'=>$admins->id)); @@ -132,7 +139,7 @@ class FoafGroupAction extends Action } $this->elementEnd('Group'); - + ksort($member_details); foreach ($member_details as $uri => $details) { if ($details['is_admin']) @@ -158,7 +165,7 @@ class FoafGroupAction extends Action )); } } - + $this->elementEnd('rdf:RDF'); $this->endXML(); } diff --git a/actions/groupdesignsettings.php b/actions/groupdesignsettings.php index e290ba514..526226a28 100644 --- a/actions/groupdesignsettings.php +++ b/actions/groupdesignsettings.php @@ -90,7 +90,10 @@ class GroupDesignSettingsAction extends DesignSettingsAction if ($groupid) { $this->group = User_group::staticGet('id', $groupid); } else { - $this->group = User_group::staticGet('nickname', $nickname); + $local = Local_group::staticGet('nickname', $nickname); + if ($local) { + $this->group = User_group::staticGet('id', $local->group_id); + } } if (!$this->group) { diff --git a/actions/grouplogo.php b/actions/grouplogo.php index 3c9b56296..f414a23cc 100644 --- a/actions/grouplogo.php +++ b/actions/grouplogo.php @@ -92,7 +92,10 @@ class GrouplogoAction extends GroupDesignAction if ($groupid) { $this->group = User_group::staticGet('id', $groupid); } else { - $this->group = User_group::staticGet('nickname', $nickname); + $local = Local_group::staticGet('nickname', $nickname); + if ($local) { + $this->group = User_group::staticGet('id', $local->group_id); + } } if (!$this->group) { diff --git a/actions/groupmembers.php b/actions/groupmembers.php index f16e972a4..a16debd7b 100644 --- a/actions/groupmembers.php +++ b/actions/groupmembers.php @@ -77,7 +77,14 @@ class GroupmembersAction extends GroupDesignAction return false; } - $this->group = User_group::staticGet('nickname', $nickname); + $local = Local_group::staticGet('nickname', $nickname); + + if (!$local) { + $this->clientError(_('No such group.'), 404); + return false; + } + + $this->group = User_group::staticGet('id', $local->group_id); if (!$this->group) { $this->clientError(_('No such group.'), 404); diff --git a/actions/grouprss.php b/actions/grouprss.php index 866fc66eb..490f6f945 100644 --- a/actions/grouprss.php +++ b/actions/grouprss.php @@ -92,7 +92,14 @@ class groupRssAction extends Rss10Action return false; } - $this->group = User_group::staticGet('nickname', $nickname); + $local = Local_group::staticGet('nickname', $nickname); + + if (!$local) { + $this->clientError(_('No such group.'), 404); + return false; + } + + $this->group = User_group::staticGet('id', $local->group_id); if (!$this->group) { $this->clientError(_('No such group.'), 404); diff --git a/actions/groups.php b/actions/groups.php index 10a1d5964..8aacff8b0 100644 --- a/actions/groups.php +++ b/actions/groups.php @@ -109,17 +109,21 @@ class GroupsAction extends Action } $offset = ($this->page-1) * GROUPS_PER_PAGE; - $limit = GROUPS_PER_PAGE + 1; + $limit = GROUPS_PER_PAGE + 1; + + $qry = 'SELECT user_group.* '. + 'from user_group join local_group on user_group.id = local_group.group_id '. + 'order by user_group.created desc '. + 'limit ' . $limit . ' offset ' . $offset; $groups = new User_group(); - $groups->orderBy('created DESC'); - $groups->limit($offset, $limit); $cnt = 0; - if ($groups->find()) { - $gl = new GroupList($groups, null, $this); - $cnt = $gl->show(); - } + + $groups->query($qry); + + $gl = new GroupList($groups, null, $this); + $cnt = $gl->show(); $this->pagination($this->page > 1, $cnt > GROUPS_PER_PAGE, $this->page, 'groups'); diff --git a/actions/joingroup.php b/actions/joingroup.php index 235e5ab4c..ba642f712 100644 --- a/actions/joingroup.php +++ b/actions/joingroup.php @@ -77,7 +77,14 @@ class JoingroupAction extends Action return false; } - $this->group = User_group::staticGet('nickname', $nickname); + $local = Local_group::staticGet('nickname', $nickname); + + if (!$local) { + $this->clientError(_('No such group.'), 404); + return false; + } + + $this->group = User_group::staticGet('id', $local->group_id); if (!$this->group) { $this->clientError(_('No such group.'), 404); diff --git a/actions/leavegroup.php b/actions/leavegroup.php index 9b9d83b6c..222d4c1b4 100644 --- a/actions/leavegroup.php +++ b/actions/leavegroup.php @@ -77,7 +77,14 @@ class LeavegroupAction extends Action return false; } - $this->group = User_group::staticGet('nickname', $nickname); + $local = Local_group::staticGet('nickname', $nickname); + + if (!$local) { + $this->clientError(_('No such group.'), 404); + return false; + } + + $this->group = User_group::staticGet('id', $local->group_id); if (!$this->group) { $this->clientError(_('No such group.'), 404); diff --git a/actions/newgroup.php b/actions/newgroup.php index 25da7f8fc..6bb3eca76 100644 --- a/actions/newgroup.php +++ b/actions/newgroup.php @@ -192,16 +192,17 @@ class NewgroupAction extends Action 'description' => $description, 'location' => $location, 'aliases' => $aliases, - 'userid' => $cur->id)); + 'userid' => $cur->id, + 'local' => true)); common_redirect($group->homeUrl(), 303); } function nicknameExists($nickname) { - $group = User_group::staticGet('nickname', $nickname); + $local = Local_group::staticGet('nickname', $nickname); - if (!empty($group)) { + if (!empty($local)) { return true; } diff --git a/actions/showgroup.php b/actions/showgroup.php index eb1238902..0139ba157 100644 --- a/actions/showgroup.php +++ b/actions/showgroup.php @@ -122,7 +122,15 @@ class ShowgroupAction extends GroupDesignAction return false; } - $this->group = User_group::staticGet('nickname', $nickname); + $local = Local_group::staticGet('nickname', $nickname); + + if (!$local) { + common_log(LOG_NOTICE, "Couldn't find local group for nickname '$nickname'"); + $this->clientError(_('No such group.'), 404); + return false; + } + + $this->group = User_group::staticGet('id', $local->group_id); if (!$this->group) { $alias = Group_alias::staticGet('alias', $nickname); diff --git a/classes/Local_group.php b/classes/Local_group.php index 02663048f..42312ec63 100644 --- a/classes/Local_group.php +++ b/classes/Local_group.php @@ -2,9 +2,8 @@ /** * Table Definition for local_group */ -require_once 'classes/Memcached_DataObject.php'; -class Local_group extends Memcached_DataObject +class Local_group extends Memcached_DataObject { ###START_AUTOCODE /* the code below is auto generated do not remove the above tag */ @@ -16,8 +15,32 @@ class Local_group extends Memcached_DataObject public $modified; // timestamp not_null default_CURRENT_TIMESTAMP /* Static get */ - function staticGet($k,$v=NULL) { return DB_DataObject::staticGet('Local_group',$k,$v); } + function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Local_group',$k,$v); } /* the code above is auto generated do not remove the tag below */ ###END_AUTOCODE + + function sequenceKey() + { + return array(false, false, false); + } + + function setNickname($nickname) + { + $this->decache(); + $qry = 'UPDATE local_group set nickname = "'.$nickname.'" where group_id = ' . $this->group_id; + + $result = $this->query($qry); + + if ($result) { + $this->nickname = $nickname; + $this->fixupTimestamps(); + $this->encache(); + } else { + common_log_db_error($local, 'UPDATE', __FILE__); + throw new ServerException(_('Could not update local group.')); + } + + return $result; + } } diff --git a/classes/User_group.php b/classes/User_group.php index 6e58a4d67..5877ce202 100644 --- a/classes/User_group.php +++ b/classes/User_group.php @@ -10,16 +10,16 @@ class User_group extends Memcached_DataObject public $__table = 'user_group'; // table name public $id; // int(4) primary_key not_null - public $nickname; // varchar(64) - public $fullname; // varchar(255) - public $homepage; // varchar(255) - public $description; // text - public $location; // varchar(255) - public $original_logo; // varchar(255) - public $homepage_logo; // varchar(255) - public $stream_logo; // varchar(255) - public $mini_logo; // varchar(255) - public $design_id; // int(4) + public $nickname; // varchar(64) + public $fullname; // varchar(255) + public $homepage; // varchar(255) + public $description; // text + public $location; // varchar(255) + public $original_logo; // varchar(255) + public $homepage_logo; // varchar(255) + public $stream_logo; // varchar(255) + public $mini_logo; // varchar(255) + public $design_id; // int(4) public $created; // datetime not_null default_0000-00-00%2000%3A00%3A00 public $modified; // timestamp not_null default_CURRENT_TIMESTAMP public $uri; // varchar(255) unique_key @@ -414,28 +414,30 @@ class User_group extends Memcached_DataObject $group->homepage = $homepage; $group->description = $description; $group->location = $location; + $group->uri = $uri; $group->created = common_sql_now(); $result = $group->insert(); if (!$result) { common_log_db_error($group, 'INSERT', __FILE__); - $this->serverError( - _('Could not create group.'), - 500, - $this->format - ); - return; + throw new ServerException(_('Could not create group.')); } + + if (!isset($uri) || empty($uri)) { + $orig = clone($group); + $group->uri = common_local_url('groupbyid', array('id' => $group->id)); + $result = $group->update($orig); + if (!$result) { + common_log_db_error($group, 'UPDATE', __FILE__); + throw new ServerException(_('Could not set group uri.')); + } + } + $result = $group->setAliases($aliases); if (!$result) { - $this->serverError( - _('Could not create aliases.'), - 500, - $this->format - ); - return; + throw new ServerException(_('Could not create aliases.')); } $member = new Group_member(); @@ -449,12 +451,22 @@ class User_group extends Memcached_DataObject if (!$result) { common_log_db_error($member, 'INSERT', __FILE__); - $this->serverError( - _('Could not set group membership.'), - 500, - $this->format - ); - return; + throw new ServerException(_('Could not set group membership.')); + } + + if ($local) { + $local_group = new Local_group(); + + $local_group->group_id = $group->id; + $local_group->nickname = $nickname; + $local_group->created = common_sql_now(); + + $result = $local_group->insert(); + + if (!$result) { + common_log_db_error($local_group, 'INSERT', __FILE__); + throw new ServerException(_('Could not save local group info.')); + } } $group->query('COMMIT'); diff --git a/lib/api.php b/lib/api.php index 0bcf4cc21..d79dc327e 100644 --- a/lib/api.php +++ b/lib/api.php @@ -1218,7 +1218,12 @@ class ApiAction extends Action return User_group::staticGet($this->arg('id')); } else if ($this->arg('id')) { $nickname = common_canonical_nickname($this->arg('id')); - return User_group::staticGet('nickname', $nickname); + $local = Local_group::staticGet('nickname', $nickname); + if (empty($local)) { + return null; + } else { + return User_group::staticGet('id', $local->id); + } } else if ($this->arg('group_id')) { // This is to ensure that a non-numeric user_id still // overrides screen_name even if it doesn't get used @@ -1227,14 +1232,24 @@ class ApiAction extends Action } } else if ($this->arg('group_name')) { $nickname = common_canonical_nickname($this->arg('group_name')); - return User_group::staticGet('nickname', $nickname); + $local = Local_group::staticGet('nickname', $nickname); + if (empty($local)) { + return null; + } else { + return User_group::staticGet('id', $local->id); + } } } else if (is_numeric($id)) { return User_group::staticGet($id); } else { $nickname = common_canonical_nickname($id); - return User_group::staticGet('nickname', $nickname); + $local = Local_group::staticGet('nickname', $nickname); + if (empty($local)) { + return null; + } else { + return User_group::staticGet('id', $local->id); + } } } -- cgit v1.2.3-54-g00ecf From 8f42d375939116eff482b3d07a8feaa4cc29c984 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Thu, 25 Feb 2010 09:24:29 -0500 Subject: Add 'mainpage' to User_group Add the mainpage attribute to user_group objects. --- classes/User_group.php | 10 ++++++++-- classes/statusnet.ini | 1 + db/statusnet.sql | 1 + 3 files changed, 10 insertions(+), 2 deletions(-) (limited to 'classes') diff --git a/classes/User_group.php b/classes/User_group.php index 5877ce202..a81eb8ce0 100644 --- a/classes/User_group.php +++ b/classes/User_group.php @@ -23,6 +23,7 @@ class User_group extends Memcached_DataObject public $created; // datetime not_null default_0000-00-00%2000%3A00%3A00 public $modified; // timestamp not_null default_CURRENT_TIMESTAMP public $uri; // varchar(255) unique_key + public $mainpage; // varchar(255) /* Static get */ function staticGet($k,$v=NULL) { return DB_DataObject::staticGet('User_group',$k,$v); } @@ -42,8 +43,13 @@ class User_group extends Memcached_DataObject { $url = null; if (Event::handle('StartUserGroupHomeUrl', array($this, &$url))) { - $url = common_local_url('showgroup', - array('nickname' => $this->nickname)); + // normally stored in mainpage, but older ones may be null + if (!empty($this->mainpage)) { + $url = $this->mainpage; + } else { + $url = common_local_url('showgroup', + array('nickname' => $this->nickname)); + } } Event::handle('EndUserGroupHomeUrl', array($this, &$url)); return $url; diff --git a/classes/statusnet.ini b/classes/statusnet.ini index 7444306f0..719dbedf5 100644 --- a/classes/statusnet.ini +++ b/classes/statusnet.ini @@ -601,6 +601,7 @@ design_id = 1 created = 142 modified = 384 uri = 2 +mainpage = 2 [user_group__keys] id = N diff --git a/db/statusnet.sql b/db/statusnet.sql index 75d060e28..4158f0167 100644 --- a/db/statusnet.sql +++ b/db/statusnet.sql @@ -422,6 +422,7 @@ create table user_group ( modified timestamp comment 'date this record was modified', uri varchar(255) unique key comment 'universal identifier', + mainpage varchar(255) comment 'page for group info to link to', index user_group_nickname_idx (nickname) -- cgit v1.2.3-54-g00ecf From d53b4b9b8411f8edbbeba57bdbc3b2e06c41c18e Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Thu, 25 Feb 2010 12:05:22 -0500 Subject: save mainpage element for groups --- actions/editgroup.php | 1 + actions/newgroup.php | 3 +++ classes/User_group.php | 1 + 3 files changed, 5 insertions(+) (limited to 'classes') diff --git a/actions/editgroup.php b/actions/editgroup.php index bbbb7a0f4..d486db0c0 100644 --- a/actions/editgroup.php +++ b/actions/editgroup.php @@ -249,6 +249,7 @@ class EditgroupAction extends GroupDesignAction $this->group->homepage = $homepage; $this->group->description = $description; $this->group->location = $location; + $this->group->mainpage = common_local_url('showgroup', array('nickname' => $nickname)); $result = $this->group->update($orig); diff --git a/actions/newgroup.php b/actions/newgroup.php index 6bb3eca76..75bc293ec 100644 --- a/actions/newgroup.php +++ b/actions/newgroup.php @@ -180,6 +180,8 @@ class NewgroupAction extends Action } } + $mainpage = common_local_url('showgroup', array('nickname' => $nickname)); + $cur = common_current_user(); // Checked in prepare() above @@ -193,6 +195,7 @@ class NewgroupAction extends Action 'location' => $location, 'aliases' => $aliases, 'userid' => $cur->id, + 'mainpage' => $mainpage, 'local' => true)); common_redirect($group->homeUrl(), 303); diff --git a/classes/User_group.php b/classes/User_group.php index a81eb8ce0..0592c56f8 100644 --- a/classes/User_group.php +++ b/classes/User_group.php @@ -421,6 +421,7 @@ class User_group extends Memcached_DataObject $group->description = $description; $group->location = $location; $group->uri = $uri; + $group->mainpage = $mainpage; $group->created = common_sql_now(); $result = $group->insert(); -- cgit v1.2.3-54-g00ecf From 2f03b2cc453d9ba60b6224b29ece398c8d6dfbda Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Thu, 25 Feb 2010 12:15:26 -0500 Subject: method for getting a group's URI --- classes/User_group.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'classes') diff --git a/classes/User_group.php b/classes/User_group.php index 0592c56f8..f24bef764 100644 --- a/classes/User_group.php +++ b/classes/User_group.php @@ -55,6 +55,21 @@ class User_group extends Memcached_DataObject return $url; } + function getUri() + { + $uri = null; + if (Event::handle('StartUserGroupGetUri', array($this, &$uri))) { + if (!empty($this->uri)) { + $uri = $this->uri; + } else { + $uri = common_local_url('groupbyid', + array('id' => $this->id)); + } + } + Event::handle('EndUserGroupGetUri', array($this, &$uri)); + return $uri; + } + function permalink() { $url = null; -- cgit v1.2.3-54-g00ecf From 79c0d52daa92b60e8eed80fa9459367c26f97122 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Thu, 25 Feb 2010 11:26:33 -0800 Subject: OStatus: save categories from the Atom entry as hashtags. --- classes/Notice.php | 37 +++++++++++++++-- lib/activity.php | 61 ++++++++++++++++++++++++++++- lib/distribqueuehandler.php | 12 ------ plugins/OStatus/classes/Ostatus_profile.php | 14 ++++++- 4 files changed, 106 insertions(+), 18 deletions(-) (limited to 'classes') diff --git a/classes/Notice.php b/classes/Notice.php index e8d5c45cb..46c5ebb37 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -121,6 +121,9 @@ class Notice extends Memcached_DataObject $result = parent::delete(); } + /** + * Extract #hashtags from this notice's content and save them to the database. + */ function saveTags() { /* extract all #hastags */ @@ -129,14 +132,22 @@ class Notice extends Memcached_DataObject return true; } + /* Add them to the database */ + return $this->saveKnownTags($match[1]); + } + + /** + * Record the given set of hash tags in the db for this notice. + * Given tag strings will be normalized and checked for dupes. + */ + function saveKnownTags($hashtags) + { //turn each into their canonical tag //this is needed to remove dupes before saving e.g. #hash.tag = #hashtag - $hashtags = array(); - for($i=0; $isaveTag($hashtag); @@ -145,6 +156,10 @@ class Notice extends Memcached_DataObject return true; } + /** + * Record a single hash tag as associated with this notice. + * Tag format and uniqueness must be validated by caller. + */ function saveTag($hashtag) { $tag = new Notice_tag(); @@ -194,6 +209,8 @@ class Notice extends Memcached_DataObject * place of extracting @-replies from content. * array 'groups' list of group IDs to deliver to, in place of * extracting ! tags from content + * array 'tags' list of hashtag strings to save with the notice + * in place of extracting # tags from content * @fixme tag override * * @return Notice @@ -343,6 +360,8 @@ class Notice extends Memcached_DataObject $notice->blowOnInsert(); + // Save per-notice metadata... + if (isset($replies)) { $notice->saveKnownReplies($replies); } else { @@ -355,6 +374,16 @@ class Notice extends Memcached_DataObject $notice->saveGroups(); } + if (isset($tags)) { + $notice->saveKnownTags($tags); + } else { + $notice->saveTags(); + } + + // @fixme pass in data for URLs too? + $notice->saveUrls(); + + // Prepare inbox delivery, may be queued to background. $notice->distribute(); return $notice; diff --git a/lib/activity.php b/lib/activity.php index 3de5f62c7..e592aad6f 100644 --- a/lib/activity.php +++ b/lib/activity.php @@ -859,6 +859,7 @@ class Activity public $content; // HTML content of activity public $id; // ID of the activity public $title; // title of the activity + public $categories = array(); // list of AtomCategory objects /** * Turns a regular old Atom into a magical activity @@ -947,6 +948,14 @@ class Activity $this->summary = ActivityUtils::childContent($entry, 'summary'); $this->id = ActivityUtils::childContent($entry, 'id'); $this->content = ActivityUtils::getContent($entry); + + $catEls = $entry->getElementsByTagNameNS(self::ATOM, 'category'); + if ($catEls) { + for ($i = 0; $i < $catEls->length; $i++) { + $catEl = $catEls->item($i); + $this->categories[] = new AtomCategory($catEl); + } + } } /** @@ -1011,6 +1020,10 @@ class Activity $xs->raw($this->target->asString('activity:target')); } + foreach ($this->categories as $cat) { + $xs->raw($cat->asString()); + } + $xs->elementEnd('entry'); return $xs->getString(); @@ -1020,4 +1033,50 @@ class Activity { return ActivityUtils::child($element, $tag, $namespace); } -} \ No newline at end of file +} + +class AtomCategory +{ + public $term; + public $scheme; + public $label; + + function __construct($element=null) + { + if ($element && $element->attributes) { + $this->term = $this->extract($element, 'term'); + $this->scheme = $this->extract($element, 'scheme'); + $this->label = $this->extract($element, 'label'); + } + } + + protected function extract($element, $attrib) + { + $node = $element->attributes->getNamedItemNS(Activity::ATOM, $attrib); + if ($node) { + return trim($node->textContent); + } + $node = $element->attributes->getNamedItem($attrib); + if ($node) { + return trim($node->textContent); + } + return null; + } + + function asString() + { + $attribs = array(); + if ($this->term !== null) { + $attribs['term'] = $this->term; + } + if ($this->scheme !== null) { + $attribs['scheme'] = $this->scheme; + } + if ($this->label !== null) { + $attribs['label'] = $this->label; + } + $xs = new XMLStringer(); + $xs->element('category', $attribs); + return $xs->asString(); + } +} diff --git a/lib/distribqueuehandler.php b/lib/distribqueuehandler.php index dc183fb36..d2be7a92c 100644 --- a/lib/distribqueuehandler.php +++ b/lib/distribqueuehandler.php @@ -62,24 +62,12 @@ class DistribQueueHandler { // XXX: do we need to change this for remote users? - try { - $notice->saveTags(); - } catch (Exception $e) { - $this->logit($notice, $e); - } - try { $notice->addToInboxes(); } catch (Exception $e) { $this->logit($notice, $e); } - try { - $notice->saveUrls(); - } catch (Exception $e) { - $this->logit($notice, $e); - } - try { Event::handle('EndNoticeSave', array($notice)); // Enqueue for other handlers diff --git a/plugins/OStatus/classes/Ostatus_profile.php b/plugins/OStatus/classes/Ostatus_profile.php index 300e38c05..d66939399 100644 --- a/plugins/OStatus/classes/Ostatus_profile.php +++ b/plugins/OStatus/classes/Ostatus_profile.php @@ -638,7 +638,9 @@ class Ostatus_profile extends Memcached_DataObject 'uri' => $sourceUri, 'rendered' => $rendered, 'replies' => array(), - 'groups' => array()); + 'groups' => array(), + 'tags' => array()); + // Check for optional attributes... @@ -673,6 +675,16 @@ class Ostatus_profile extends Memcached_DataObject } } + // Atom categories <-> hashtags + foreach ($activity->categories as $cat) { + if ($cat->term) { + $term = common_canonical_tag($cat->term); + if ($term) { + $options['tags'][] = $term; + } + } + } + try { $saved = Notice::saveNew($oprofile->profile_id, $content, -- cgit v1.2.3-54-g00ecf From e61edb55d9c92c0c93de3a591928f4760b6cea16 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Thu, 25 Feb 2010 13:34:43 -0800 Subject: Rationalize group activity stuff --- classes/User_group.php | 46 ++++++++++++++++++++++++------------- lib/activity.php | 61 ++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 90 insertions(+), 17 deletions(-) (limited to 'classes') diff --git a/classes/User_group.php b/classes/User_group.php index f24bef764..7240e2703 100644 --- a/classes/User_group.php +++ b/classes/User_group.php @@ -399,25 +399,41 @@ class User_group extends Memcached_DataObject return $xs->getString(); } + /** + * Returns an XML string fragment with group information as an + * Activity Streams element. + * + * Assumes that 'activity' namespace has been previously defined. + * + * @return string + */ function asActivitySubject() { - $xs = new XMLStringer(true); + return $this->asActivityNoun('subject'); + } - $xs->elementStart('activity:subject'); - $xs->element('activity:object', null, 'http://activitystrea.ms/schema/1.0/group'); - $xs->element('id', null, $this->permalink()); - $xs->element('title', null, $this->getBestName()); - $xs->element( - 'link', array( - 'rel' => 'avatar', - 'href' => empty($this->homepage_logo) - ? User_group::defaultLogo(AVATAR_PROFILE_SIZE) - : $this->homepage_logo - ) - ); - $xs->elementEnd('activity:subject'); + /** + * Returns an XML string fragment with group information as an + * Activity Streams noun object with the given element type. + * + * Assumes that 'activity', 'georss', and 'poco' namespace has been + * previously defined. + * + * @param string $element one of 'actor', 'subject', 'object', 'target' + * + * @return string + */ + function asActivityNoun($element) + { + $noun = ActivityObject::fromGroup($this); + return $noun->asString('activity:' . $element); + } - return $xs->getString(); + function getAvatar() + { + return empty($this->homepage_logo) + ? User_group::defaultLogo(AVATAR_PROFILE_SIZE) + : $this->homepage_logo; } static function register($fields) { diff --git a/lib/activity.php b/lib/activity.php index e592aad6f..0863cf8fa 100644 --- a/lib/activity.php +++ b/lib/activity.php @@ -223,6 +223,37 @@ class PoCo return $poco; } + function fromGroup($group) + { + if (empty($group)) { + return null; + } + + $poco = new PoCo(); + + $poco->preferredUsername = $group->nickname; + $poco->displayName = $group->getBestName(); + + $poco->note = $group->description; + + $paddy = new PoCoAddress(); + $paddy->formatted = $group->location; + $poco->address = $paddy; + + if (!empty($group->homepage)) { + array_push( + $poco->urls, + new PoCoURL( + 'homepage', + $group->homepage, + true + ) + ); + } + + return $poco; + } + function getPrimaryURL() { foreach ($this->urls as $url) { @@ -621,6 +652,21 @@ class ActivityObject return $object; } + static function fromGroup($group) + { + $object = new ActivityObject(); + + $object->type = ActivityObject::GROUP; + $object->id = $group->getUri(); + $object->title = $group->getBestName(); + $object->link = $group->getUri(); + $object->avatar = $group->getAvatar(); + + $object->poco = PoCo::fromGroup($group); + + return $object; + } + function asString($tag='activity:object') { $xs = new XMLStringer(true); @@ -656,8 +702,7 @@ class ActivityObject ); } - if ($this->type == ActivityObject::PERSON - || $this->type == ActivityObject::GROUP) { + if ($this->type == ActivityObject::PERSON) { $xs->element( 'link', array( 'type' => empty($this->avatar) ? 'image/png' : $this->avatar->mediatype, @@ -670,6 +715,18 @@ class ActivityObject ); } + // XXX: Gotta figure out mime-type! Gar. + + if ($this->type == ActivityObject::GROUP) { + $xs->element( + 'link', array( + 'rel' => 'avatar', + 'href' => $this->avatar + ), + null + ); + } + if (!empty($this->geopoint)) { $xs->element( 'georss:point', -- cgit v1.2.3-54-g00ecf From 7922edb5b6c4ad55a1b81fa16c93e5656b676b26 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Thu, 25 Feb 2010 16:06:49 -0800 Subject: Add lots of fun avatars to our Atom output --- classes/Notice.php | 1 + lib/activity.php | 146 ++++++++++++++++++++++------ lib/atomnoticefeed.php | 5 + plugins/OStatus/classes/Ostatus_profile.php | 3 +- 4 files changed, 124 insertions(+), 31 deletions(-) (limited to 'classes') diff --git a/classes/Notice.php b/classes/Notice.php index 46c5ebb37..ac4640534 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -1096,6 +1096,7 @@ class Notice extends Memcached_DataObject 'xmlns:thr' => 'http://purl.org/syndication/thread/1.0', 'xmlns:georss' => 'http://www.georss.org/georss', 'xmlns:activity' => 'http://activitystrea.ms/spec/1.0/', + 'xmlns:media' => 'http://purl.org/syndication/atommedia', 'xmlns:poco' => 'http://portablecontacts.net/spec/1.0', 'xmlns:ostatus' => 'http://ostatus.org/schema/1.0'); } else { diff --git a/lib/activity.php b/lib/activity.php index 30cdc5a56..0f30e8bf5 100644 --- a/lib/activity.php +++ b/lib/activity.php @@ -465,6 +465,57 @@ class ActivityUtils } } +// XXX: Arg! This wouldn't be necessary if we used Avatars conistently +class AvatarLink +{ + public $url; + public $type; + public $size; + public $width; + + static function fromAvatar($avatar) + { + if (empty($avatar)) { + return null; + } + $alink = new AvatarLink(); + $alink->type = $avatar->mediatype; + $alink->height = $avatar->mediatype; + $alink->width = $avatar->width; + $alink->url = $avatar->displayUrl(); + return $alink; + } + + static function fromFilename($filename, $size) + { + $alink = new AvatarLink(); + $alink->url = $filename; + $alink->height = $size; + if (!empty($filename)) { + $alink->width = $size; + $alink->type = self::mediatype($filename); + } else { + $alink->url = User_group::defaultLogo($size); + $alink->type = 'image/png'; + } + return $alink; + } + + // yuck! + static function mediatype($filename) { + $ext = strtolower(end(explode('.', $filename))); + if ($ext == 'jpeg') { + $ext = 'jpg'; + } + // hope we don't support any others + $types = array('png', 'gif', 'jpg', 'jpeg'); + if (in_array($ext, $types)) { + return 'image/' . $ext; + } + return null; + } +} + /** * A noun-ish thing in the activity universe * @@ -521,7 +572,7 @@ class ActivityObject public $content; public $link; public $source; - public $avatar; + public $avatarLinks = array(); public $geopoint; public $poco; public $displayName; @@ -641,13 +692,40 @@ class ActivityObject $object->id = $profile->getUri(); $object->title = $profile->getBestName(); $object->link = $profile->profileurl; - $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE); - if ($avatar) { - $object->avatar = $avatar->displayUrl(); + + $orig = $profile->getOriginalAvatar(); + + if (!empty($orig)) { + $object->avatarLinks[] = AvatarLink::fromAvatar($orig); + } + + $sizes = array( + AVATAR_PROFILE_SIZE, + AVATAR_STREAM_SIZE, + AVATAR_MINI_SIZE + ); + + foreach ($sizes as $size) { + + $alink = null; + $avatar = $profile->getAvatar($size); + + if (!empty($avatar)) { + $alink = AvatarLink::fromAvatar($avatar); + } else { + $alink = new AvatarLink(); + $alink->type = 'image/png'; + $alink->height = $size; + $alink->width = $size; + $alink->url = Avatar::defaultImage($size); + } + + $object->avatarLinks[] = $alink; } if (isset($profile->lat) && isset($profile->lon)) { - $object->geopoint = (float)$profile->lat . ' ' . (float)$profile->lon; + $object->geopoint = (float)$profile->lat + . ' ' . (float)$profile->lon; } $object->poco = PoCo::fromProfile($profile); @@ -663,13 +741,28 @@ class ActivityObject $object->id = $group->getUri(); $object->title = $group->getBestName(); $object->link = $group->getUri(); - $object->avatar = $group->getAvatar(); + + $object->avatarLinks[] = AvatarLink::fromFilename( + $group->homepage_logo, + AVATAR_PROFILE_SIZE + ); + + $object->avatarLinks[] = AvatarLink::fromFilename( + $group->stream_logo, + AVATAR_STREAM_SIZE + ); + + $object->avatarLinks[] = AvatarLink::fromFilename( + $group->mini_logo, + AVATAR_MINI_SIZE + ); $object->poco = PoCo::fromGroup($group); return $object; } + function asString($tag='activity:object') { $xs = new XMLStringer(true); @@ -705,29 +798,21 @@ class ActivityObject ); } - if ($this->type == ActivityObject::PERSON) { - $xs->element( - 'link', array( - 'type' => empty($this->avatar) ? 'image/png' : $this->avatar->mediatype, - 'rel' => 'avatar', - 'href' => empty($this->avatar) - ? Avatar::defaultImage(AVATAR_PROFILE_SIZE) - : $this->avatar - ), - null - ); - } - - // XXX: Gotta figure out mime-type! Gar. - - if ($this->type == ActivityObject::GROUP) { - $xs->element( - 'link', array( - 'rel' => 'avatar', - 'href' => $this->avatar - ), - null - ); + if ($this->type == ActivityObject::PERSON + || $this->type == ActivityObject::GROUP) { + + foreach ($this->avatarLinks as $avatar) { + $xs->element( + 'link', array( + 'rel' => 'avatar', + 'type' => $avatar->type, + 'media:width' => $avatar->width, + 'media:height' => $avatar->height, + 'href' => $avatar->url + ), + null + ); + } } if (!empty($this->geopoint)) { @@ -1038,7 +1123,8 @@ class Activity 'xmlns:activity' => 'http://activitystrea.ms/spec/1.0/', 'xmlns:georss' => 'http://www.georss.org/georss', 'xmlns:ostatus' => 'http://ostatus.org/schema/1.0', - 'xmlns:poco' => 'http://portablecontacts.net/spec/1.0'); + 'xmlns:poco' => 'http://portablecontacts.net/spec/1.0', + 'xmlns:media' => 'http://purl.org/syndication/atommedia'); } else { $attrs = array(); } diff --git a/lib/atomnoticefeed.php b/lib/atomnoticefeed.php index d2bf2a416..3c3556cb9 100644 --- a/lib/atomnoticefeed.php +++ b/lib/atomnoticefeed.php @@ -64,6 +64,11 @@ class AtomNoticeFeed extends Atom10Feed 'http://activitystrea.ms/spec/1.0/' ); + $this->addNamespace( + 'media', + 'http://purl.org/syndication/atommedia' + ); + $this->addNamespace( 'poco', 'http://portablecontacts.net/spec/1.0' diff --git a/plugins/OStatus/classes/Ostatus_profile.php b/plugins/OStatus/classes/Ostatus_profile.php index f23017077..7026d82f2 100644 --- a/plugins/OStatus/classes/Ostatus_profile.php +++ b/plugins/OStatus/classes/Ostatus_profile.php @@ -401,7 +401,8 @@ class Ostatus_profile extends Memcached_DataObject 'xmlns:thr' => 'http://purl.org/syndication/thread/1.0', 'xmlns:georss' => 'http://www.georss.org/georss', 'xmlns:ostatus' => 'http://ostatus.org/schema/1.0', - 'xmlns:poco' => 'http://portablecontacts.net/spec/1.0'); + 'xmlns:poco' => 'http://portablecontacts.net/spec/1.0', + 'xmlns:media' => 'http://purl.org/syndication/atommedia'); $entry = new XMLStringer(); $entry->elementStart('entry', $attributes); -- cgit v1.2.3-54-g00ecf From 3aee8e04486684c6aebbafbecac123bba4553427 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Thu, 25 Feb 2010 21:46:53 -0800 Subject: Fix a few keys that got dropped from statusnet.ini by mistake --- classes/statusnet.ini | 3 +++ 1 file changed, 3 insertions(+) (limited to 'classes') diff --git a/classes/statusnet.ini b/classes/statusnet.ini index 719dbedf5..3fb8ee208 100644 --- a/classes/statusnet.ini +++ b/classes/statusnet.ini @@ -55,6 +55,7 @@ modified = 384 [conversation__keys] id = N +uri = U [deleted_notice] id = 129 @@ -102,6 +103,7 @@ modified = 384 [file__keys] id = N +url = U [file_oembed] file_id = 129 @@ -385,6 +387,7 @@ modified = 384 [oauth_application__keys] id = N +name = U [oauth_application_user] profile_id = 129 -- cgit v1.2.3-54-g00ecf