Merge branch '0.7.x' into 0.8.x
Conflicts: classes/Notice.php classes/Profile.php lib/common.php lib/util.php scripts/getvaliddaemons.php scripts/stopdaemons.sh
This commit is contained in:
commit
adfb79a9bb
60
README
60
README
|
@ -2,8 +2,8 @@
|
||||||
README
|
README
|
||||||
------
|
------
|
||||||
|
|
||||||
Laconica 0.7.3 ("You Are The Everything")
|
Laconica 0.7.4 ("Can't Get There From Here")
|
||||||
7 April 2009
|
29 May 2009
|
||||||
|
|
||||||
This is the README file for Laconica, the Open Source microblogging
|
This is the README file for Laconica, the Open Source microblogging
|
||||||
platform. It includes installation instructions, descriptions of
|
platform. It includes installation instructions, descriptions of
|
||||||
|
@ -71,29 +71,29 @@ for additional terms.
|
||||||
New this version
|
New this version
|
||||||
================
|
================
|
||||||
|
|
||||||
This is a minor bug-fix and feature release since version 0.7.2.1,
|
This is a minor bug-fix and feature release since version 0.7.3,
|
||||||
released Mar 11 2009. Notable changes this version:
|
released Apr 4 2009. Notable changes this version:
|
||||||
|
|
||||||
- A plugin to allow a templating language for customization
|
- Improved handling of UTF-8 characters. The new code is *not* backwards
|
||||||
- A plugin for Piwik Analytics engine
|
compatible by default; see "Upgrading" below for instructions on
|
||||||
- A bookmarklet for posting a notice about a Web page you're reading
|
converting existing databases to the correct character set.
|
||||||
- A welcome notice ('welcomebot') and default subscription for new users
|
- Unroll joins for large queries. This greatly enhanced database
|
||||||
- Support for SSL for some or all pages on the site
|
performance -- up to 50x for some queries -- at the expense of making
|
||||||
- Better handling of empty notice lists on many pages
|
an extra DB hit for some queries.
|
||||||
- Major improvements to the Twitter friend-sync offline processing
|
- Added an optional plugin to use WikiHashtags
|
||||||
- subscribers, subscriptions, groups are listed on the Personal page.
|
(http://hashtags.wikia.com/) for the sidebar on hashtag pages.
|
||||||
- "Invite" link restored to main menu
|
- Optimized Twitter friend synchronization.
|
||||||
- Better memory handling in FOAF output
|
- Better error handling for Ajax posting of notices, including
|
||||||
- Fix for SUP support (FriendFeed)
|
HTTP errors and timeouts.
|
||||||
- Correct and intelligent redirect HTTP status codes
|
- Experimental Comet plugin -- supports the cometd and the Bayeux
|
||||||
- Fix DB collations for search and sort
|
protocol. Using this plugin, you can show "real time" updates on the
|
||||||
- Better H1s and Titles using user full names
|
public and tag pages. However, server configuration is complex.
|
||||||
- Fixes to make the linkback plugin operational
|
- If queues are enabled, update inboxes and memcached off-line. Speeds
|
||||||
- Better indication that a notice is being published by Ajax (spinner)
|
up posting considerably.
|
||||||
- Better and unified Atom output
|
- Correctly shorten links posted through XMPP.
|
||||||
- Hiding "register" and "join now" messages when site is closed
|
- <link> elements for pagination, supported by some browsers like Opera.
|
||||||
- ping, twitter and facebook queuehandlers working better
|
- Corrected date format in search API.
|
||||||
- Updated RPM spec
|
- Made the public XRDS file work correctly.
|
||||||
|
|
||||||
Prerequisites
|
Prerequisites
|
||||||
=============
|
=============
|
||||||
|
@ -197,9 +197,9 @@ especially if you've previously installed PHP/MySQL packages.
|
||||||
1. Unpack the tarball you downloaded on your Web server. Usually a
|
1. Unpack the tarball you downloaded on your Web server. Usually a
|
||||||
command like this will work:
|
command like this will work:
|
||||||
|
|
||||||
tar zxf laconica-0.7.3.tar.gz
|
tar zxf laconica-0.7.4.tar.gz
|
||||||
|
|
||||||
...which will make a laconica-0.7.3 subdirectory in your current
|
...which will make a laconica-0.7.4 subdirectory in your current
|
||||||
directory. (If you don't have shell access on your Web server, you
|
directory. (If you don't have shell access on your Web server, you
|
||||||
may have to unpack the tarball on your local computer and FTP the
|
may have to unpack the tarball on your local computer and FTP the
|
||||||
files to the server.)
|
files to the server.)
|
||||||
|
@ -207,7 +207,7 @@ especially if you've previously installed PHP/MySQL packages.
|
||||||
2. Move the tarball to a directory of your choosing in your Web root
|
2. Move the tarball to a directory of your choosing in your Web root
|
||||||
directory. Usually something like this will work:
|
directory. Usually something like this will work:
|
||||||
|
|
||||||
mv laconica-0.7.3 /var/www/mublog
|
mv laconica-0.7.4 /var/www/mublog
|
||||||
|
|
||||||
This will make your Laconica instance available in the mublog path of
|
This will make your Laconica instance available in the mublog path of
|
||||||
your server, like "http://example.net/mublog". "microblog" or
|
your server, like "http://example.net/mublog". "microblog" or
|
||||||
|
@ -704,7 +704,7 @@ with this situation.
|
||||||
If you've been using Laconica 0.6, 0.5 or lower, or if you've been
|
If you've been using Laconica 0.6, 0.5 or lower, or if you've been
|
||||||
tracking the "git" version of the software, you will probably want
|
tracking the "git" version of the software, you will probably want
|
||||||
to upgrade and keep your existing data. There is no automated upgrade
|
to upgrade and keep your existing data. There is no automated upgrade
|
||||||
procedure in Laconica 0.7.3. Try these step-by-step instructions; read
|
procedure in Laconica 0.7.4. Try these step-by-step instructions; read
|
||||||
to the end first before trying them.
|
to the end first before trying them.
|
||||||
|
|
||||||
0. Download Laconica and set up all the prerequisites as if you were
|
0. Download Laconica and set up all the prerequisites as if you were
|
||||||
|
@ -1239,7 +1239,7 @@ repository (see below), and you get a compilation error ("unexpected
|
||||||
T_STRING") in the browser, check to see that you don't have any
|
T_STRING") in the browser, check to see that you don't have any
|
||||||
conflicts in your code.
|
conflicts in your code.
|
||||||
|
|
||||||
If you upgraded to Laconica 0.7.3 without reading the "Notice inboxes"
|
If you upgraded to Laconica 0.7.4 without reading the "Notice inboxes"
|
||||||
section above, and all your users' 'Personal' tabs are empty, read the
|
section above, and all your users' 'Personal' tabs are empty, read the
|
||||||
"Notice inboxes" section above.
|
"Notice inboxes" section above.
|
||||||
|
|
||||||
|
@ -1330,6 +1330,8 @@ if anyone's been overlooked in error.
|
||||||
* Ken Sedgwick
|
* Ken Sedgwick
|
||||||
* Brian Hendrickson
|
* Brian Hendrickson
|
||||||
* Tobias Diekershoff
|
* Tobias Diekershoff
|
||||||
|
* Dan Moore
|
||||||
|
* Fil
|
||||||
|
|
||||||
Thanks also to the developers of our upstream library code and to the
|
Thanks also to the developers of our upstream library code and to the
|
||||||
thousands of people who have tried out Identi.ca, installed Laconi.ca,
|
thousands of people who have tried out Identi.ca, installed Laconi.ca,
|
||||||
|
|
|
@ -144,8 +144,8 @@ class ApiAction extends Action
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_array($fullname, $bareauth)) {
|
if (in_array($fullname, $bareauth)) {
|
||||||
# bareauth: only needs auth if without an argument
|
# bareauth: only needs auth if without an argument or query param specifying user
|
||||||
if ($this->api_arg) {
|
if ($this->api_arg || $this->arg('id') || is_numeric($this->arg('user_id')) || $this->arg('screen_name')) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -122,7 +122,7 @@ class ShownoticeAction extends Action
|
||||||
|
|
||||||
function lastModified()
|
function lastModified()
|
||||||
{
|
{
|
||||||
return max(strtotime($this->notice->created),
|
return max(strtotime($this->notice->modified),
|
||||||
strtotime($this->profile->modified),
|
strtotime($this->profile->modified),
|
||||||
($this->avatar) ? strtotime($this->avatar->modified) : 0);
|
($this->avatar) ? strtotime($this->avatar->modified) : 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,9 +98,31 @@ class TwitapiaccountAction extends TwitterapiAction
|
||||||
$this->serverError(_('API method under construction.'), $code=501);
|
$this->serverError(_('API method under construction.'), $code=501);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We don't have a rate limit, but some clients check this method.
|
||||||
|
// It always returns the same thing: 100 hit left.
|
||||||
function rate_limit_status($args, $apidata)
|
function rate_limit_status($args, $apidata)
|
||||||
{
|
{
|
||||||
parent::handle($args);
|
parent::handle($args);
|
||||||
$this->serverError(_('API method under construction.'), $code=501);
|
|
||||||
|
$type = $apidata['content-type'];
|
||||||
|
$this->init_document($type);
|
||||||
|
|
||||||
|
if ($apidata['content-type'] == 'xml') {
|
||||||
|
$this->elementStart('hash');
|
||||||
|
$this->element('remaining-hits', array('type' => 'integer'), 100);
|
||||||
|
$this->element('hourly-limit', array('type' => 'integer'), 100);
|
||||||
|
$this->element('reset-time', array('type' => 'datetime'), null);
|
||||||
|
$this->element('reset_time_in_seconds', array('type' => 'integer'), 0);
|
||||||
|
$this->elementEnd('hash');
|
||||||
|
} elseif ($apidata['content-type'] == 'json') {
|
||||||
|
|
||||||
|
$out = array('reset_time_in_seconds' => 0,
|
||||||
|
'remaining_hits' => 100,
|
||||||
|
'hourly_limit' => 100,
|
||||||
|
'reset_time' => '');
|
||||||
|
print json_encode($out);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->end_document($type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ class Twitapidirect_messagesAction extends TwitterapiAction
|
||||||
$count = $this->arg('count');
|
$count = $this->arg('count');
|
||||||
$since = $this->arg('since');
|
$since = $this->arg('since');
|
||||||
$since_id = $this->arg('since_id');
|
$since_id = $this->arg('since_id');
|
||||||
$before_id = $this->arg('before_id');
|
$max_id = $this->arg('max_id');
|
||||||
|
|
||||||
$page = $this->arg('page');
|
$page = $this->arg('page');
|
||||||
|
|
||||||
|
@ -74,8 +74,8 @@ class Twitapidirect_messagesAction extends TwitterapiAction
|
||||||
$link = $server . $user->nickname . '/outbox';
|
$link = $server . $user->nickname . '/outbox';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($before_id) {
|
if ($max_id) {
|
||||||
$message->whereAdd("id < $before_id");
|
$message->whereAdd("id <= $max_id");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($since_id) {
|
if ($since_id) {
|
||||||
|
|
|
@ -45,22 +45,21 @@ class TwitapistatusesAction extends TwitterapiAction
|
||||||
|
|
||||||
$page = $this->arg('page');
|
$page = $this->arg('page');
|
||||||
$since_id = $this->arg('since_id');
|
$since_id = $this->arg('since_id');
|
||||||
$before_id = $this->arg('before_id');
|
$max_id = $this->arg('max_id');
|
||||||
|
|
||||||
// NOTE: page, since_id, and before_id are extensions to Twitter API -- TB
|
|
||||||
if (!$page) {
|
if (!$page) {
|
||||||
$page = 1;
|
$page = 1;
|
||||||
}
|
}
|
||||||
if (!$since_id) {
|
if (!$since_id) {
|
||||||
$since_id = 0;
|
$since_id = 0;
|
||||||
}
|
}
|
||||||
if (!$before_id) {
|
if (!$max_id) {
|
||||||
$before_id = 0;
|
$max_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
$since = strtotime($this->arg('since'));
|
$since = strtotime($this->arg('since'));
|
||||||
|
|
||||||
$notice = Notice::publicStream((($page-1)*$MAX_PUBSTATUSES), $MAX_PUBSTATUSES, $since_id, $before_id, $since);
|
$notice = Notice::publicStream((($page-1)*$MAX_PUBSTATUSES), $MAX_PUBSTATUSES, $since_id, $max_id, $since);
|
||||||
|
|
||||||
if ($notice) {
|
if ($notice) {
|
||||||
|
|
||||||
|
@ -97,7 +96,7 @@ class TwitapistatusesAction extends TwitterapiAction
|
||||||
$since_id = $this->arg('since_id');
|
$since_id = $this->arg('since_id');
|
||||||
$count = $this->arg('count');
|
$count = $this->arg('count');
|
||||||
$page = $this->arg('page');
|
$page = $this->arg('page');
|
||||||
$before_id = $this->arg('before_id');
|
$max_id = $this->arg('max_id');
|
||||||
|
|
||||||
if (!$page) {
|
if (!$page) {
|
||||||
$page = 1;
|
$page = 1;
|
||||||
|
@ -111,9 +110,8 @@ class TwitapistatusesAction extends TwitterapiAction
|
||||||
$since_id = 0;
|
$since_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: before_id is an extension to Twitter API -- TB
|
if (!$max_id) {
|
||||||
if (!$before_id) {
|
$max_id = 0;
|
||||||
$before_id = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$since = strtotime($this->arg('since'));
|
$since = strtotime($this->arg('since'));
|
||||||
|
@ -133,7 +131,7 @@ class TwitapistatusesAction extends TwitterapiAction
|
||||||
$link = common_local_url('all', array('nickname' => $user->nickname));
|
$link = common_local_url('all', array('nickname' => $user->nickname));
|
||||||
$subtitle = sprintf(_('Updates from %1$s and friends on %2$s!'), $user->nickname, $sitename);
|
$subtitle = sprintf(_('Updates from %1$s and friends on %2$s!'), $user->nickname, $sitename);
|
||||||
|
|
||||||
$notice = $user->noticesWithFriends(($page-1)*20, $count, $since_id, $before_id, $since);
|
$notice = $user->noticesWithFriends(($page-1)*20, $count, $since_id, $max_id, $since);
|
||||||
|
|
||||||
switch($apidata['content-type']) {
|
switch($apidata['content-type']) {
|
||||||
case 'xml':
|
case 'xml':
|
||||||
|
@ -184,7 +182,7 @@ class TwitapistatusesAction extends TwitterapiAction
|
||||||
$since = $this->arg('since');
|
$since = $this->arg('since');
|
||||||
$since_id = $this->arg('since_id');
|
$since_id = $this->arg('since_id');
|
||||||
$page = $this->arg('page');
|
$page = $this->arg('page');
|
||||||
$before_id = $this->arg('before_id');
|
$max_id = $this->arg('max_id');
|
||||||
|
|
||||||
if (!$page) {
|
if (!$page) {
|
||||||
$page = 1;
|
$page = 1;
|
||||||
|
@ -198,9 +196,8 @@ class TwitapistatusesAction extends TwitterapiAction
|
||||||
$since_id = 0;
|
$since_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: before_id is an extensions to Twitter API -- TB
|
if (!$max_id) {
|
||||||
if (!$before_id) {
|
$max_id = 0;
|
||||||
$before_id = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$since = strtotime($this->arg('since'));
|
$since = strtotime($this->arg('since'));
|
||||||
|
@ -220,7 +217,7 @@ class TwitapistatusesAction extends TwitterapiAction
|
||||||
|
|
||||||
# XXX: since
|
# XXX: since
|
||||||
|
|
||||||
$notice = $user->getNotices((($page-1)*20), $count, $since_id, $before_id, $since);
|
$notice = $user->getNotices((($page-1)*20), $count, $since_id, $max_id, $since);
|
||||||
|
|
||||||
switch($apidata['content-type']) {
|
switch($apidata['content-type']) {
|
||||||
case 'xml':
|
case 'xml':
|
||||||
|
@ -353,7 +350,7 @@ class TwitapistatusesAction extends TwitterapiAction
|
||||||
$count = $this->arg('count');
|
$count = $this->arg('count');
|
||||||
$page = $this->arg('page');
|
$page = $this->arg('page');
|
||||||
$since_id = $this->arg('since_id');
|
$since_id = $this->arg('since_id');
|
||||||
$before_id = $this->arg('before_id');
|
$max_id = $this->arg('max_id');
|
||||||
|
|
||||||
$user = $this->get_user($apidata['api_arg'], $apidata);
|
$user = $this->get_user($apidata['api_arg'], $apidata);
|
||||||
$this->auth_user = $apidata['user'];
|
$this->auth_user = $apidata['user'];
|
||||||
|
@ -380,15 +377,14 @@ class TwitapistatusesAction extends TwitterapiAction
|
||||||
$since_id = 0;
|
$since_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: before_id is an extension to Twitter API -- TB
|
if (!$max_id) {
|
||||||
if (!$before_id) {
|
$max_id = 0;
|
||||||
$before_id = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$since = strtotime($this->arg('since'));
|
$since = strtotime($this->arg('since'));
|
||||||
|
|
||||||
$notice = $user->getReplies((($page-1)*20),
|
$notice = $user->getReplies((($page-1)*20),
|
||||||
$count, $since_id, $before_id, $since);
|
$count, $since_id, $max_id, $since);
|
||||||
$notices = array();
|
$notices = array();
|
||||||
|
|
||||||
while ($notice->fetch()) {
|
while ($notice->fetch()) {
|
||||||
|
|
|
@ -25,110 +25,61 @@ class TwitapiusersAction extends TwitterapiAction
|
||||||
{
|
{
|
||||||
|
|
||||||
function show($args, $apidata)
|
function show($args, $apidata)
|
||||||
{
|
{
|
||||||
parent::handle($args);
|
parent::handle($args);
|
||||||
|
|
||||||
if (!in_array($apidata['content-type'], array('xml', 'json'))) {
|
if (!in_array($apidata['content-type'], array('xml', 'json'))) {
|
||||||
$this->clientError(_('API method not found!'), $code = 404);
|
$this->clientError(_('API method not found!'), $code = 404);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$user = null;
|
|
||||||
$email = $this->arg('email');
|
|
||||||
$user_id = $this->arg('user_id');
|
|
||||||
|
|
||||||
if ($email) {
|
$user = null;
|
||||||
$user = User::staticGet('email', $email);
|
$email = $this->arg('email');
|
||||||
} elseif ($user_id) {
|
$user_id = $this->arg('user_id');
|
||||||
$user = $this->get_user($user_id);
|
|
||||||
} elseif (isset($apidata['api_arg'])) {
|
|
||||||
$user = $this->get_user($apidata['api_arg']);
|
|
||||||
} elseif (isset($apidata['user'])) {
|
|
||||||
$user = $apidata['user'];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$user) {
|
|
||||||
// XXX: Twitter returns a random(?) user instead of throwing and err! -- Zach
|
|
||||||
$this->client_error(_('Not found.'), 404, $apidata['content-type']);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$profile = $user->getProfile();
|
// XXX: email field deprecated in Twitter's API
|
||||||
|
|
||||||
if (!$profile) {
|
// XXX: Also: need to add screen_name param
|
||||||
common_server_error(_('User has no profile.'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$twitter_user = $this->twitter_user_array($profile, true);
|
if ($email) {
|
||||||
|
$user = User::staticGet('email', $email);
|
||||||
|
} elseif ($user_id) {
|
||||||
|
$user = $this->get_user($user_id);
|
||||||
|
} elseif (isset($apidata['api_arg'])) {
|
||||||
|
$user = $this->get_user($apidata['api_arg']);
|
||||||
|
} elseif (isset($apidata['user'])) {
|
||||||
|
$user = $apidata['user'];
|
||||||
|
}
|
||||||
|
|
||||||
// Add in extended user fields offered up by this method
|
if (!$user) {
|
||||||
$twitter_user['created_at'] = $this->date_twitter($profile->created);
|
$this->client_error(_('Not found.'), 404, $apidata['content-type']);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$subbed = DB_DataObject::factory('subscription');
|
$profile = $user->getProfile();
|
||||||
$subbed->subscriber = $profile->id;
|
|
||||||
$subbed_count = (int) $subbed->count() - 1;
|
|
||||||
|
|
||||||
$notices = DB_DataObject::factory('notice');
|
if (!$profile) {
|
||||||
$notices->profile_id = $profile->id;
|
common_server_error(_('User has no profile.'));
|
||||||
$notice_count = (int) $notices->count();
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$twitter_user['friends_count'] = (is_int($subbed_count)) ? $subbed_count : 0;
|
$twitter_user = $this->twitter_user_array($profile, true);
|
||||||
$twitter_user['statuses_count'] = (is_int($notice_count)) ? $notice_count : 0;
|
|
||||||
|
|
||||||
// Other fields Twitter sends...
|
if ($apidata['content-type'] == 'xml') {
|
||||||
$twitter_user['profile_background_color'] = '';
|
$this->init_document('xml');
|
||||||
$twitter_user['profile_background_image_url'] = '';
|
$this->show_twitter_xml_user($twitter_user);
|
||||||
$twitter_user['profile_text_color'] = '';
|
$this->end_document('xml');
|
||||||
$twitter_user['profile_link_color'] = '';
|
} elseif ($apidata['content-type'] == 'json') {
|
||||||
$twitter_user['profile_sidebar_fill_color'] = '';
|
$this->init_document('json');
|
||||||
$twitter_user['profile_sidebar_border_color'] = '';
|
$this->show_json_objects($twitter_user);
|
||||||
$twitter_user['profile_background_tile'] = false;
|
$this->end_document('json');
|
||||||
|
} else {
|
||||||
|
|
||||||
$faves = DB_DataObject::factory('fave');
|
// This is in case 'show' was called via /account/verify_credentials
|
||||||
$faves->user_id = $user->id;
|
// without a format (xml or json).
|
||||||
$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($apidata['user'])) {
|
|
||||||
|
|
||||||
$twitter_user['following'] = $apidata['user']->isSubscribed($profile);
|
|
||||||
|
|
||||||
// Notifications on?
|
|
||||||
$sub = Subscription::pkeyGet(array('subscriber' =>
|
|
||||||
$apidata['user']->id, 'subscribed' => $profile->id));
|
|
||||||
|
|
||||||
if ($sub) {
|
|
||||||
$twitter_user['notifications'] = ($sub->jabber || $sub->sms);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($apidata['content-type'] == 'xml') {
|
|
||||||
$this->init_document('xml');
|
|
||||||
$this->show_twitter_xml_user($twitter_user);
|
|
||||||
$this->end_document('xml');
|
|
||||||
} elseif ($apidata['content-type'] == 'json') {
|
|
||||||
$this->init_document('json');
|
|
||||||
$this->show_json_objects($twitter_user);
|
|
||||||
$this->end_document('json');
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// This is in case 'show' was called via /account/verify_credentials
|
|
||||||
// without a format (xml or json).
|
|
||||||
header('Content-Type: text/html; charset=utf-8');
|
header('Content-Type: text/html; charset=utf-8');
|
||||||
print 'Authorized';
|
print 'Authorized';
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ class Fave extends Memcached_DataObject
|
||||||
return $ids;
|
return $ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _streamDirect($user_id, $offset, $limit, $since_id, $before_id, $since)
|
function _streamDirect($user_id, $offset, $limit, $since_id, $max_id, $since)
|
||||||
{
|
{
|
||||||
$fav = new Fave();
|
$fav = new Fave();
|
||||||
|
|
||||||
|
@ -59,8 +59,8 @@ class Fave extends Memcached_DataObject
|
||||||
$fav->whereAdd('notice_id > ' . $since_id);
|
$fav->whereAdd('notice_id > ' . $since_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($before_id != 0) {
|
if ($max_id != 0) {
|
||||||
$fav->whereAdd('notice_id < ' . $before_id);
|
$fav->whereAdd('notice_id <= ' . $max_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_null($since)) {
|
if (!is_null($since)) {
|
||||||
|
|
|
@ -239,8 +239,14 @@ class Memcached_DataObject extends DB_DataObject
|
||||||
$result = parent::_connect();
|
$result = parent::_connect();
|
||||||
if (!$exists) {
|
if (!$exists) {
|
||||||
$DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
|
$DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
|
||||||
if (common_config('db', 'utf8')) {
|
if (common_config('db', 'type') == 'mysql' &&
|
||||||
$DB->query('SET NAMES "utf8"');
|
common_config('db', 'utf8')) {
|
||||||
|
$conn = $DB->connection;
|
||||||
|
if ($DB instanceof DB_mysqli) {
|
||||||
|
mysqli_set_charset($conn, 'utf8');
|
||||||
|
} else if ($DB instanceof DB_mysql) {
|
||||||
|
mysql_set_charset('utf8', $conn);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $result;
|
return $result;
|
||||||
|
|
|
@ -124,6 +124,8 @@ class Notice extends Memcached_DataObject
|
||||||
|
|
||||||
$profile = Profile::staticGet($profile_id);
|
$profile = Profile::staticGet($profile_id);
|
||||||
|
|
||||||
|
$final = common_shorten_links($content);
|
||||||
|
|
||||||
if (!$profile) {
|
if (!$profile) {
|
||||||
common_log(LOG_ERR, 'Problem saving notice. Unknown user.');
|
common_log(LOG_ERR, 'Problem saving notice. Unknown user.');
|
||||||
return _('Problem saving notice. Unknown user.');
|
return _('Problem saving notice. Unknown user.');
|
||||||
|
@ -134,7 +136,7 @@ class Notice extends Memcached_DataObject
|
||||||
return _('Too many notices too fast; take a breather and post again in a few minutes.');
|
return _('Too many notices too fast; take a breather and post again in a few minutes.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (common_config('site', 'dupelimit') > 0 && !Notice::checkDupes($profile_id, $content)) {
|
if (common_config('site', 'dupelimit') > 0 && !Notice::checkDupes($profile_id, $final)) {
|
||||||
common_log(LOG_WARNING, 'Dupe posting by profile #' . $profile_id . '; throttled.');
|
common_log(LOG_WARNING, 'Dupe posting by profile #' . $profile_id . '; throttled.');
|
||||||
return _('Too many duplicate messages too quickly; take a breather and post again in a few minutes.');
|
return _('Too many duplicate messages too quickly; take a breather and post again in a few minutes.');
|
||||||
}
|
}
|
||||||
|
@ -165,8 +167,8 @@ class Notice extends Memcached_DataObject
|
||||||
|
|
||||||
$notice->reply_to = $reply_to;
|
$notice->reply_to = $reply_to;
|
||||||
$notice->created = common_sql_now();
|
$notice->created = common_sql_now();
|
||||||
$notice->content = $content;
|
$notice->content = $final;
|
||||||
$notice->rendered = common_render_content($content, $notice);
|
$notice->rendered = common_render_content($final, $notice);
|
||||||
$notice->source = $source;
|
$notice->source = $source;
|
||||||
$notice->uri = $uri;
|
$notice->uri = $uri;
|
||||||
|
|
||||||
|
@ -202,13 +204,9 @@ class Notice extends Memcached_DataObject
|
||||||
|
|
||||||
$notice->saveReplies();
|
$notice->saveReplies();
|
||||||
$notice->saveTags();
|
$notice->saveTags();
|
||||||
$notice->saveGroups();
|
|
||||||
|
|
||||||
if (common_config('queue', 'enabled')) {
|
$notice->addToInboxes();
|
||||||
$notice->addToAuthorInbox();
|
$notice->saveGroups();
|
||||||
} else {
|
|
||||||
$notice->addToInboxes();
|
|
||||||
}
|
|
||||||
|
|
||||||
$notice->query('COMMIT');
|
$notice->query('COMMIT');
|
||||||
|
|
||||||
|
@ -218,13 +216,7 @@ class Notice extends Memcached_DataObject
|
||||||
# Clear the cache for subscribed users, so they'll update at next request
|
# Clear the cache for subscribed users, so they'll update at next request
|
||||||
# XXX: someone clever could prepend instead of clearing the cache
|
# XXX: someone clever could prepend instead of clearing the cache
|
||||||
|
|
||||||
if (common_config('memcached', 'enabled')) {
|
$notice->blowCaches();
|
||||||
if (common_config('queue', 'enabled')) {
|
|
||||||
$notice->blowAuthorCaches();
|
|
||||||
} else {
|
|
||||||
$notice->blowCaches();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $notice;
|
return $notice;
|
||||||
}
|
}
|
||||||
|
@ -297,17 +289,6 @@ class Notice extends Memcached_DataObject
|
||||||
$this->blowGroupCache($blowLast);
|
$this->blowGroupCache($blowLast);
|
||||||
}
|
}
|
||||||
|
|
||||||
function blowAuthorCaches($blowLast=false)
|
|
||||||
{
|
|
||||||
// Clear the user's cache
|
|
||||||
$cache = common_memcache();
|
|
||||||
if (!empty($cache)) {
|
|
||||||
$cache->delete(common_cache_key('notice_inbox:by_user:'.$this->profile_id));
|
|
||||||
}
|
|
||||||
$this->blowNoticeCache($blowLast);
|
|
||||||
$this->blowPublicCache($blowLast);
|
|
||||||
}
|
|
||||||
|
|
||||||
function blowGroupCache($blowLast=false)
|
function blowGroupCache($blowLast=false)
|
||||||
{
|
{
|
||||||
$cache = common_memcache();
|
$cache = common_memcache();
|
||||||
|
@ -443,22 +424,22 @@ class Notice extends Memcached_DataObject
|
||||||
# XXX: too many args; we need to move to named params or even a separate
|
# XXX: too many args; we need to move to named params or even a separate
|
||||||
# class for notice streams
|
# class for notice streams
|
||||||
|
|
||||||
static function getStream($qry, $cachekey, $offset=0, $limit=20, $since_id=0, $before_id=0, $order=null, $since=null) {
|
static function getStream($qry, $cachekey, $offset=0, $limit=20, $since_id=0, $max_id=0, $order=null, $since=null) {
|
||||||
|
|
||||||
if (common_config('memcached', 'enabled')) {
|
if (common_config('memcached', 'enabled')) {
|
||||||
|
|
||||||
# Skip the cache if this is a since, since_id or before_id qry
|
# Skip the cache if this is a since, since_id or max_id qry
|
||||||
if ($since_id > 0 || $before_id > 0 || $since) {
|
if ($since_id > 0 || $max_id > 0 || $since) {
|
||||||
return Notice::getStreamDirect($qry, $offset, $limit, $since_id, $before_id, $order, $since);
|
return Notice::getStreamDirect($qry, $offset, $limit, $since_id, $max_id, $order, $since);
|
||||||
} else {
|
} else {
|
||||||
return Notice::getCachedStream($qry, $cachekey, $offset, $limit, $order);
|
return Notice::getCachedStream($qry, $cachekey, $offset, $limit, $order);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Notice::getStreamDirect($qry, $offset, $limit, $since_id, $before_id, $order, $since);
|
return Notice::getStreamDirect($qry, $offset, $limit, $since_id, $max_id, $order, $since);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function getStreamDirect($qry, $offset, $limit, $since_id, $before_id, $order, $since) {
|
static function getStreamDirect($qry, $offset, $limit, $since_id, $max_id, $order, $since) {
|
||||||
|
|
||||||
$needAnd = false;
|
$needAnd = false;
|
||||||
$needWhere = true;
|
$needWhere = true;
|
||||||
|
@ -480,7 +461,7 @@ class Notice extends Memcached_DataObject
|
||||||
$qry .= ' notice.id > ' . $since_id;
|
$qry .= ' notice.id > ' . $since_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($before_id > 0) {
|
if ($max_id > 0) {
|
||||||
|
|
||||||
if ($needWhere) {
|
if ($needWhere) {
|
||||||
$qry .= ' WHERE ';
|
$qry .= ' WHERE ';
|
||||||
|
@ -489,7 +470,7 @@ class Notice extends Memcached_DataObject
|
||||||
$qry .= ' AND ';
|
$qry .= ' AND ';
|
||||||
}
|
}
|
||||||
|
|
||||||
$qry .= ' notice.id < ' . $before_id;
|
$qry .= ' notice.id <= ' . $max_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($since) {
|
if ($since) {
|
||||||
|
@ -647,17 +628,17 @@ class Notice extends Memcached_DataObject
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function publicStream($offset=0, $limit=20, $since_id=0, $before_id=0, $since=null)
|
function publicStream($offset=0, $limit=20, $since_id=0, $max_id=0, $since=null)
|
||||||
{
|
{
|
||||||
$ids = Notice::stream(array('Notice', '_publicStreamDirect'),
|
$ids = Notice::stream(array('Notice', '_publicStreamDirect'),
|
||||||
array(),
|
array(),
|
||||||
'public',
|
'public',
|
||||||
$offset, $limit, $since_id, $before_id, $since);
|
$offset, $limit, $since_id, $max_id, $since);
|
||||||
|
|
||||||
return Notice::getStreamByIds($ids);
|
return Notice::getStreamByIds($ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _publicStreamDirect($offset=0, $limit=20, $since_id=0, $before_id=0, $since=null)
|
function _publicStreamDirect($offset=0, $limit=20, $since_id=0, $max_id=0, $since=null)
|
||||||
{
|
{
|
||||||
$notice = new Notice();
|
$notice = new Notice();
|
||||||
|
|
||||||
|
@ -681,8 +662,8 @@ class Notice extends Memcached_DataObject
|
||||||
$notice->whereAdd('id > ' . $since_id);
|
$notice->whereAdd('id > ' . $since_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($before_id != 0) {
|
if ($max_id != 0) {
|
||||||
$notice->whereAdd('id < ' . $before_id);
|
$notice->whereAdd('id <= ' . $max_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_null($since)) {
|
if (!is_null($since)) {
|
||||||
|
@ -726,33 +707,6 @@ class Notice extends Memcached_DataObject
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addToAuthorInbox()
|
|
||||||
{
|
|
||||||
$enabled = common_config('inboxes', 'enabled');
|
|
||||||
|
|
||||||
if ($enabled === true || $enabled === 'transitional') {
|
|
||||||
$user = User::staticGet('id', $this->profile_id);
|
|
||||||
if (empty($user)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$inbox = new Notice_inbox();
|
|
||||||
$UT = common_config('db','type')=='pgsql'?'"user"':'user';
|
|
||||||
$qry = 'INSERT INTO notice_inbox (user_id, notice_id, created) ' .
|
|
||||||
"SELECT $UT.id, " . $this->id . ", '" . $this->created . "' " .
|
|
||||||
"FROM $UT " .
|
|
||||||
"WHERE $UT.id = " . $this->profile_id . ' ' .
|
|
||||||
'AND NOT EXISTS (SELECT user_id, notice_id ' .
|
|
||||||
'FROM notice_inbox ' .
|
|
||||||
"WHERE user_id = " . $this->profile_id . ' '.
|
|
||||||
'AND notice_id = ' . $this->id . ' )';
|
|
||||||
if ($enabled === 'transitional') {
|
|
||||||
$qry .= " AND $UT.inboxed = 1";
|
|
||||||
}
|
|
||||||
$inbox->query($qry);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
function saveGroups()
|
function saveGroups()
|
||||||
{
|
{
|
||||||
$enabled = common_config('inboxes', 'enabled');
|
$enabled = common_config('inboxes', 'enabled');
|
||||||
|
@ -1024,15 +978,15 @@ class Notice extends Memcached_DataObject
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function stream($fn, $args, $cachekey, $offset=0, $limit=20, $since_id=0, $before_id=0, $since=null, $tag=null)
|
function stream($fn, $args, $cachekey, $offset=0, $limit=20, $since_id=0, $max_id=0, $since=null)
|
||||||
{
|
{
|
||||||
$cache = common_memcache();
|
$cache = common_memcache();
|
||||||
|
|
||||||
if (empty($cache) ||
|
if (empty($cache) ||
|
||||||
$since_id != 0 || $before_id != 0 || !is_null($since) ||
|
$since_id != 0 || $max_id != 0 || (!is_null($since) && $since > 0) ||
|
||||||
($offset + $limit) > NOTICE_CACHE_WINDOW) {
|
($offset + $limit) > NOTICE_CACHE_WINDOW) {
|
||||||
return call_user_func_array($fn, array_merge($args, array($offset, $limit, $since_id,
|
return call_user_func_array($fn, array_merge($args, array($offset, $limit, $since_id,
|
||||||
$before_id, $since, $tag)));
|
$max_id, $since)));
|
||||||
}
|
}
|
||||||
|
|
||||||
$idkey = common_cache_key($cachekey);
|
$idkey = common_cache_key($cachekey);
|
||||||
|
|
|
@ -43,15 +43,15 @@ class Notice_inbox extends Memcached_DataObject
|
||||||
/* the code above is auto generated do not remove the tag below */
|
/* the code above is auto generated do not remove the tag below */
|
||||||
###END_AUTOCODE
|
###END_AUTOCODE
|
||||||
|
|
||||||
function stream($user_id, $offset, $limit, $since_id, $before_id, $since)
|
function stream($user_id, $offset, $limit, $since_id, $max_id, $since)
|
||||||
{
|
{
|
||||||
return Notice::stream(array('Notice_inbox', '_streamDirect'),
|
return Notice::stream(array('Notice_inbox', '_streamDirect'),
|
||||||
array($user_id),
|
array($user_id),
|
||||||
'notice_inbox:by_user:'.$user_id,
|
'notice_inbox:by_user:'.$user_id,
|
||||||
$offset, $limit, $since_id, $before_id, $since);
|
$offset, $limit, $since_id, $max_id, $since);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _streamDirect($user_id, $offset, $limit, $since_id, $before_id, $since)
|
function _streamDirect($user_id, $offset, $limit, $since_id, $max_id, $since)
|
||||||
{
|
{
|
||||||
$inbox = new Notice_inbox();
|
$inbox = new Notice_inbox();
|
||||||
|
|
||||||
|
@ -61,8 +61,8 @@ class Notice_inbox extends Memcached_DataObject
|
||||||
$inbox->whereAdd('notice_id > ' . $since_id);
|
$inbox->whereAdd('notice_id > ' . $since_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($before_id != 0) {
|
if ($max_id != 0) {
|
||||||
$inbox->whereAdd('notice_id < ' . $before_id);
|
$inbox->whereAdd('notice_id <= ' . $max_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_null($since)) {
|
if (!is_null($since)) {
|
||||||
|
|
|
@ -46,7 +46,7 @@ class Notice_tag extends Memcached_DataObject
|
||||||
return Notice::getStreamByIds($ids);
|
return Notice::getStreamByIds($ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _streamDirect($tag, $offset, $limit, $since_id, $before_id, $since)
|
function _streamDirect($tag, $offset, $limit, $since_id, $max_id, $since)
|
||||||
{
|
{
|
||||||
$nt = new Notice_tag();
|
$nt = new Notice_tag();
|
||||||
|
|
||||||
|
@ -59,8 +59,8 @@ class Notice_tag extends Memcached_DataObject
|
||||||
$nt->whereAdd('notice_id > ' . $since_id);
|
$nt->whereAdd('notice_id > ' . $since_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($before_id != 0) {
|
if ($max_id != 0) {
|
||||||
$nt->whereAdd('notice_id < ' . $before_id);
|
$nt->whereAdd('notice_id < ' . $max_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_null($since)) {
|
if (!is_null($since)) {
|
||||||
|
|
|
@ -170,7 +170,7 @@ class Profile extends Memcached_DataObject
|
||||||
$ids = Notice::stream(array($this, '_streamDirect'),
|
$ids = Notice::stream(array($this, '_streamDirect'),
|
||||||
array(),
|
array(),
|
||||||
'profile:notice_ids:' . $this->id,
|
'profile:notice_ids:' . $this->id,
|
||||||
$offset, $limit, $since_id, $before_id, $since);
|
$offset, $limit, $since_id, $max_id, $since);
|
||||||
|
|
||||||
return Notice::getStreamByIds($ids);
|
return Notice::getStreamByIds($ids);
|
||||||
}
|
}
|
||||||
|
@ -225,8 +225,8 @@ class Profile extends Memcached_DataObject
|
||||||
$notice->whereAdd('id > ' . $since_id);
|
$notice->whereAdd('id > ' . $since_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($before_id != 0) {
|
if ($max_id != 0) {
|
||||||
$notice->whereAdd('id < ' . $before_id);
|
$notice->whereAdd('id <= ' . $max_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_null($since)) {
|
if (!is_null($since)) {
|
||||||
|
|
|
@ -22,16 +22,16 @@ class Reply extends Memcached_DataObject
|
||||||
/* the code above is auto generated do not remove the tag below */
|
/* the code above is auto generated do not remove the tag below */
|
||||||
###END_AUTOCODE
|
###END_AUTOCODE
|
||||||
|
|
||||||
function stream($user_id, $offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=null)
|
function stream($user_id, $offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $max_id=0, $since=null)
|
||||||
{
|
{
|
||||||
$ids = Notice::stream(array('Reply', '_streamDirect'),
|
$ids = Notice::stream(array('Reply', '_streamDirect'),
|
||||||
array($user_id),
|
array($user_id),
|
||||||
'reply:stream:' . $user_id,
|
'reply:stream:' . $user_id,
|
||||||
$offset, $limit, $since_id, $before_id, $since);
|
$offset, $limit, $since_id, $max_id, $since);
|
||||||
return $ids;
|
return $ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _streamDirect($user_id, $offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=null)
|
function _streamDirect($user_id, $offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $max_id=0, $since=null)
|
||||||
{
|
{
|
||||||
$reply = new Reply();
|
$reply = new Reply();
|
||||||
$reply->profile_id = $user_id;
|
$reply->profile_id = $user_id;
|
||||||
|
@ -40,8 +40,8 @@ class Reply extends Memcached_DataObject
|
||||||
$reply->whereAdd('notice_id > ' . $since_id);
|
$reply->whereAdd('notice_id > ' . $since_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($before_id != 0) {
|
if ($max_id != 0) {
|
||||||
$reply->whereAdd('notice_id < ' . $before_id);
|
$reply->whereAdd('notice_id < ' . $max_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_null($since)) {
|
if (!is_null($since)) {
|
||||||
|
|
|
@ -403,7 +403,6 @@ class User extends Memcached_DataObject
|
||||||
function getReplies($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=null)
|
function getReplies($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=null)
|
||||||
{
|
{
|
||||||
$ids = Reply::stream($this->id, $offset, $limit, $since_id, $before_id, $since);
|
$ids = Reply::stream($this->id, $offset, $limit, $since_id, $before_id, $since);
|
||||||
common_debug("Ids = " . implode(',', $ids));
|
|
||||||
return Notice::getStreamByIds($ids);
|
return Notice::getStreamByIds($ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ class User_group extends Memcached_DataObject
|
||||||
return Notice::getStreamByIds($ids);
|
return Notice::getStreamByIds($ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _streamDirect($offset, $limit, $since_id, $before_id, $since)
|
function _streamDirect($offset, $limit, $since_id, $max_id, $since)
|
||||||
{
|
{
|
||||||
$inbox = new Group_inbox();
|
$inbox = new Group_inbox();
|
||||||
|
|
||||||
|
@ -71,8 +71,8 @@ class User_group extends Memcached_DataObject
|
||||||
$inbox->whereAdd('notice_id > ' . $since_id);
|
$inbox->whereAdd('notice_id > ' . $since_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($before_id != 0) {
|
if ($max_id != 0) {
|
||||||
$inbox->whereAdd('notice_id < ' . $before_id);
|
$inbox->whereAdd('notice_id <= ' . $max_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_null($since)) {
|
if (!is_null($since)) {
|
||||||
|
|
|
@ -2,7 +2,9 @@ INSERT INTO notice_source
|
||||||
(code, name, url, created)
|
(code, name, url, created)
|
||||||
VALUES
|
VALUES
|
||||||
('adium', 'Adium', 'http://www.adiumx.com/', now()),
|
('adium', 'Adium', 'http://www.adiumx.com/', now()),
|
||||||
|
('Afficheur', 'Afficheur', 'http://afficheur.sourceforge.jp/', now()),
|
||||||
('AgentSolo.com','AgentSolo.com','http://www.agentsolo.com/', now()),
|
('AgentSolo.com','AgentSolo.com','http://www.agentsolo.com/', now()),
|
||||||
|
('anyio', 'Any.IO', 'http://any.io/', now()),
|
||||||
('betwittered','BeTwittered','http://www.32hours.com/betwitteredinfo/', now()),
|
('betwittered','BeTwittered','http://www.32hours.com/betwitteredinfo/', now()),
|
||||||
('bti','bti','http://gregkh.github.com/bti/', now()),
|
('bti','bti','http://gregkh.github.com/bti/', now()),
|
||||||
('cliqset', 'Cliqset', 'http://www.cliqset.com/', now()),
|
('cliqset', 'Cliqset', 'http://www.cliqset.com/', now()),
|
||||||
|
@ -11,6 +13,7 @@ VALUES
|
||||||
('eventbox','EventBox','http://thecosmicmachine.com/eventbox/ ', now()),
|
('eventbox','EventBox','http://thecosmicmachine.com/eventbox/ ', now()),
|
||||||
('Facebook','Facebook','http://apps.facebook.com/identica/', now()),
|
('Facebook','Facebook','http://apps.facebook.com/identica/', now()),
|
||||||
('feed2omb','feed2omb','http://projects.ciarang.com/p/feed2omb/', now()),
|
('feed2omb','feed2omb','http://projects.ciarang.com/p/feed2omb/', now()),
|
||||||
|
('get2gnow', 'get2gnow', 'http://uberchicgeekchick.com/?projects=get2gnow', now()),
|
||||||
('gravity', 'Gravity', 'http://mobileways.de/gravity', now()),
|
('gravity', 'Gravity', 'http://mobileways.de/gravity', now()),
|
||||||
('Gwibber','Gwibber','http://launchpad.net/gwibber', now()),
|
('Gwibber','Gwibber','http://launchpad.net/gwibber', now()),
|
||||||
('HelloTxt','HelloTxt','http://hellotxt.com/', now()),
|
('HelloTxt','HelloTxt','http://hellotxt.com/', now()),
|
||||||
|
|
|
@ -335,6 +335,7 @@ function mail_broadcast_notice_sms($notice)
|
||||||
"FROM $UT JOIN subscription " .
|
"FROM $UT JOIN subscription " .
|
||||||
"ON $UT.id = subscription.subscriber " .
|
"ON $UT.id = subscription.subscriber " .
|
||||||
'WHERE subscription.subscribed = ' . $notice->profile_id . ' ' .
|
'WHERE subscription.subscribed = ' . $notice->profile_id . ' ' .
|
||||||
|
'AND subscription.subscribed != subscription.subscriber ' .
|
||||||
"AND $UT.smsemail IS NOT null " .
|
"AND $UT.smsemail IS NOT null " .
|
||||||
"AND $UT.smsnotify = 1 " .
|
"AND $UT.smsnotify = 1 " .
|
||||||
'AND subscription.sms = 1 ');
|
'AND subscription.sms = 1 ');
|
||||||
|
|
10
lib/omb.php
10
lib/omb.php
|
@ -159,13 +159,9 @@ function omb_post_notice($notice, $remote_profile, $subscription)
|
||||||
|
|
||||||
function omb_post_notice_keys($notice, $postnoticeurl, $tk, $secret)
|
function omb_post_notice_keys($notice, $postnoticeurl, $tk, $secret)
|
||||||
{
|
{
|
||||||
|
|
||||||
common_debug('Posting notice ' . $notice->id . ' to ' . $postnoticeurl, __FILE__);
|
|
||||||
|
|
||||||
$user = User::staticGet('id', $notice->profile_id);
|
$user = User::staticGet('id', $notice->profile_id);
|
||||||
|
|
||||||
if (!$user) {
|
if (!$user) {
|
||||||
common_debug('Failed to get user for notice ' . $notice->id . ', profile = ' . $notice->profile_id, __FILE__);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,8 +204,6 @@ function omb_post_notice_keys($notice, $postnoticeurl, $tk, $secret)
|
||||||
$req->to_postdata(),
|
$req->to_postdata(),
|
||||||
array('User-Agent: Laconica/' . LACONICA_VERSION));
|
array('User-Agent: Laconica/' . LACONICA_VERSION));
|
||||||
|
|
||||||
common_debug('Got HTTP result "'.print_r($result,true).'"', __FILE__);
|
|
||||||
|
|
||||||
if ($result->status == 403) { # not authorized, don't send again
|
if ($result->status == 403) { # not authorized, don't send again
|
||||||
common_debug('403 result, deleting subscription', __FILE__);
|
common_debug('403 result, deleting subscription', __FILE__);
|
||||||
# FIXME: figure out how to delete this
|
# FIXME: figure out how to delete this
|
||||||
|
@ -286,14 +280,10 @@ function omb_update_profile($profile, $remote_profile, $subscription)
|
||||||
|
|
||||||
$fetcher = Auth_Yadis_Yadis::getHTTPFetcher();
|
$fetcher = Auth_Yadis_Yadis::getHTTPFetcher();
|
||||||
|
|
||||||
common_debug('request URL = '.$req->get_normalized_http_url(), __FILE__);
|
|
||||||
common_debug('postdata = '.$req->to_postdata(), __FILE__);
|
|
||||||
$result = $fetcher->post($req->get_normalized_http_url(),
|
$result = $fetcher->post($req->get_normalized_http_url(),
|
||||||
$req->to_postdata(),
|
$req->to_postdata(),
|
||||||
array('User-Agent: Laconica/' . LACONICA_VERSION));
|
array('User-Agent: Laconica/' . LACONICA_VERSION));
|
||||||
|
|
||||||
common_debug('Got HTTP result "'.print_r($result,true).'"', __FILE__);
|
|
||||||
|
|
||||||
if (empty($result) || !$result) {
|
if (empty($result) || !$result) {
|
||||||
common_debug("Unable to contact " . $req->get_normalized_http_url());
|
common_debug("Unable to contact " . $req->get_normalized_http_url());
|
||||||
} else if ($result->status == 403) { # not authorized, don't send again
|
} else if ($result->status == 403) { # not authorized, don't send again
|
||||||
|
|
|
@ -54,7 +54,7 @@ class TwitterapiAction extends Action
|
||||||
/**
|
/**
|
||||||
* Overrides XMLOutputter::element to write booleans as strings (true|false).
|
* Overrides XMLOutputter::element to write booleans as strings (true|false).
|
||||||
* See that method's documentation for more info.
|
* See that method's documentation for more info.
|
||||||
*
|
*
|
||||||
* @param string $tag Element type or tagname
|
* @param string $tag Element type or tagname
|
||||||
* @param array $attrs Array of element attributes, as
|
* @param array $attrs Array of element attributes, as
|
||||||
* key-value pairs
|
* key-value pairs
|
||||||
|
@ -70,24 +70,85 @@ class TwitterapiAction extends Action
|
||||||
|
|
||||||
return parent::element($tag, $attrs, $content);
|
return parent::element($tag, $attrs, $content);
|
||||||
}
|
}
|
||||||
|
|
||||||
function twitter_user_array($profile, $get_notice=false)
|
function twitter_user_array($profile, $get_notice=false)
|
||||||
{
|
{
|
||||||
|
|
||||||
$twitter_user = array();
|
$twitter_user = array();
|
||||||
|
|
||||||
$twitter_user['name'] = $profile->getBestName();
|
|
||||||
$twitter_user['followers_count'] = $this->count_subscriptions($profile);
|
|
||||||
$twitter_user['screen_name'] = $profile->nickname;
|
|
||||||
$twitter_user['description'] = ($profile->bio) ? $profile->bio : null;
|
|
||||||
$twitter_user['location'] = ($profile->location) ? $profile->location : null;
|
|
||||||
$twitter_user['id'] = intval($profile->id);
|
$twitter_user['id'] = intval($profile->id);
|
||||||
|
$twitter_user['name'] = $profile->getBestName();
|
||||||
|
$twitter_user['screen_name'] = $profile->nickname;
|
||||||
|
$twitter_user['location'] = ($profile->location) ? $profile->location : null;
|
||||||
|
$twitter_user['description'] = ($profile->bio) ? $profile->bio : null;
|
||||||
|
|
||||||
$avatar = $profile->getAvatar(AVATAR_STREAM_SIZE);
|
$avatar = $profile->getAvatar(AVATAR_STREAM_SIZE);
|
||||||
|
$twitter_user['profile_image_url'] = ($avatar) ? $avatar->displayUrl() :
|
||||||
|
Avatar::defaultImage(AVATAR_STREAM_SIZE);
|
||||||
|
|
||||||
$twitter_user['profile_image_url'] = ($avatar) ? $avatar->displayUrl() : Avatar::defaultImage(AVATAR_STREAM_SIZE);
|
|
||||||
$twitter_user['protected'] = false; # not supported by Laconica yet
|
|
||||||
$twitter_user['url'] = ($profile->homepage) ? $profile->homepage : null;
|
$twitter_user['url'] = ($profile->homepage) ? $profile->homepage : null;
|
||||||
|
$twitter_user['protected'] = false; # not supported by Laconica yet
|
||||||
|
$twitter_user['followers_count'] = $this->count_subscriptions($profile);
|
||||||
|
|
||||||
|
// To be supported soon...
|
||||||
|
$twitter_user['profile_background_color'] = '';
|
||||||
|
$twitter_user['profile_text_color'] = '';
|
||||||
|
$twitter_user['profile_link_color'] = '';
|
||||||
|
$twitter_user['profile_sidebar_fill_color'] = '';
|
||||||
|
$twitter_user['profile_sidebar_border_color'] = '';
|
||||||
|
|
||||||
|
$subbed = DB_DataObject::factory('subscription');
|
||||||
|
$subbed->subscriber = $profile->id;
|
||||||
|
$subbed_count = (int) $subbed->count() - 1;
|
||||||
|
$twitter_user['friends_count'] = (is_int($subbed_count)) ? $subbed_count : 0;
|
||||||
|
|
||||||
|
$twitter_user['created_at'] = $this->date_twitter($profile->created);
|
||||||
|
|
||||||
|
$faves = DB_DataObject::factory('fave');
|
||||||
|
$faves->user_id = $user->id;
|
||||||
|
$faves_count = (int) $faves->count();
|
||||||
|
$twitter_user['favourites_count'] = $faves_count; // British spelling!
|
||||||
|
|
||||||
|
// Need to pull up the user for some of this
|
||||||
|
$user = User::staticGet($profile->id);
|
||||||
|
|
||||||
|
$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;
|
||||||
|
|
||||||
|
// To be supported some day, perhaps
|
||||||
|
$twitter_user['profile_background_image_url'] = '';
|
||||||
|
$twitter_user['profile_background_tile'] = false;
|
||||||
|
|
||||||
|
$notices = DB_DataObject::factory('notice');
|
||||||
|
$notices->profile_id = $profile->id;
|
||||||
|
$notice_count = (int) $notices->count();
|
||||||
|
|
||||||
|
$twitter_user['statuses_count'] = (is_int($notice_count)) ? $notice_count : 0;
|
||||||
|
|
||||||
|
// Is the requesting user following this user?
|
||||||
|
$twitter_user['following'] = false;
|
||||||
|
$twitter_user['notifications'] = false;
|
||||||
|
|
||||||
|
if (isset($apidata['user'])) {
|
||||||
|
|
||||||
|
$twitter_user['following'] = $apidata['user']->isSubscribed($profile);
|
||||||
|
|
||||||
|
// Notifications on?
|
||||||
|
$sub = Subscription::pkeyGet(array('subscriber' =>
|
||||||
|
$apidata['user']->id, 'subscribed' => $profile->id));
|
||||||
|
|
||||||
|
if ($sub) {
|
||||||
|
$twitter_user['notifications'] = ($sub->jabber || $sub->sms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ($get_notice) {
|
if ($get_notice) {
|
||||||
$notice = $profile->getCurrentNotice();
|
$notice = $profile->getCurrentNotice();
|
||||||
|
@ -612,7 +673,27 @@ class TwitterapiAction extends Action
|
||||||
function get_user($id, $apidata=null)
|
function get_user($id, $apidata=null)
|
||||||
{
|
{
|
||||||
if (!$id) {
|
if (!$id) {
|
||||||
return $apidata['user'];
|
|
||||||
|
// Twitter supports these other ways of passing the user ID
|
||||||
|
if (is_numeric($this->arg('id'))) {
|
||||||
|
return User::staticGet($this->arg('id'));
|
||||||
|
} else if ($this->arg('id')) {
|
||||||
|
$nickname = common_canonical_nickname($this->arg('id'));
|
||||||
|
return User::staticGet('nickname', $nickname);
|
||||||
|
} else if ($this->arg('user_id')) {
|
||||||
|
// This is to ensure that a non-numeric user_id still
|
||||||
|
// overrides screen_name even if it doesn't get used
|
||||||
|
if (is_numeric($this->arg('user_id'))) {
|
||||||
|
return User::staticGet('id', $this->arg('user_id'));
|
||||||
|
}
|
||||||
|
} else if ($this->arg('screen_name')) {
|
||||||
|
$nickname = common_canonical_nickname($this->arg('screen_name'));
|
||||||
|
return User::staticGet('nickname', $nickname);
|
||||||
|
} else {
|
||||||
|
// Fall back to trying the currently authenticated user
|
||||||
|
return $apidata['user'];
|
||||||
|
}
|
||||||
|
|
||||||
} else if (is_numeric($id)) {
|
} else if (is_numeric($id)) {
|
||||||
return User::staticGet($id);
|
return User::staticGet($id);
|
||||||
} else {
|
} else {
|
||||||
|
|
28
lib/util.php
28
lib/util.php
|
@ -900,6 +900,34 @@ function common_enqueue_notice($notice)
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function common_post_inbox_transports()
|
||||||
|
{
|
||||||
|
$transports = array('omb', 'sms');
|
||||||
|
|
||||||
|
if (common_config('xmpp', 'enabled')) {
|
||||||
|
$transports = array_merge($transports, array('jabber', 'public'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $transports;
|
||||||
|
}
|
||||||
|
|
||||||
|
function common_enqueue_notice_transport($notice, $transport)
|
||||||
|
{
|
||||||
|
$qi = new Queue_item();
|
||||||
|
$qi->notice_id = $notice->id;
|
||||||
|
$qi->transport = $transport;
|
||||||
|
$qi->created = $notice->created;
|
||||||
|
$result = $qi->insert();
|
||||||
|
if (!$result) {
|
||||||
|
$last_error = &PEAR::getStaticProperty('DB_DataObject','lastError');
|
||||||
|
common_log(LOG_ERR, 'DB error inserting queue item: ' . $last_error->message);
|
||||||
|
throw new ServerException('DB error inserting queue item: ' . $last_error->message);
|
||||||
|
>>>>>>> 0.7.x:lib/util.php
|
||||||
|
}
|
||||||
|
common_log(LOG_DEBUG, 'complete queueing notice ID = ' . $notice->id . ' for ' . $transport);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
function common_real_broadcast($notice, $remote=false)
|
function common_real_broadcast($notice, $remote=false)
|
||||||
{
|
{
|
||||||
$success = true;
|
$success = true;
|
||||||
|
|
|
@ -35,107 +35,334 @@ define('LACONICA', true);
|
||||||
require_once(INSTALLDIR . '/lib/common.php');
|
require_once(INSTALLDIR . '/lib/common.php');
|
||||||
require_once('DB.php');
|
require_once('DB.php');
|
||||||
|
|
||||||
function fixup_utf8($id) {
|
class UTF8FixerUpper
|
||||||
|
{
|
||||||
|
var $dbl = null;
|
||||||
|
var $dbu = null;
|
||||||
|
var $args = array();
|
||||||
|
|
||||||
$dbl = doConnect('latin1');
|
function __construct($args)
|
||||||
|
{
|
||||||
|
$this->args = $args;
|
||||||
|
|
||||||
if (empty($dbl)) {
|
if (array_key_exists('max_date', $args)) {
|
||||||
return;
|
$this->max_date = strftime('%Y-%m-%d %H:%M:%S', strtotime($args['max_date']));
|
||||||
|
} else {
|
||||||
|
$this->max_date = strftime('%Y-%m-%d %H:%M:%S', time());
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->dbl = $this->doConnect('latin1');
|
||||||
|
|
||||||
|
if (empty($this->dbl)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->dbu = $this->doConnect('utf8');
|
||||||
|
|
||||||
|
if (empty($this->dbu)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$dbu = doConnect('utf8');
|
function doConnect($charset)
|
||||||
|
{
|
||||||
|
$db = DB::connect(common_config('db', 'database'),
|
||||||
|
array('persistent' => false));
|
||||||
|
|
||||||
if (empty($dbu)) {
|
if (PEAR::isError($db)) {
|
||||||
return;
|
echo "ERROR: " . $db->getMessage() . "\n";
|
||||||
}
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// Do a separate DB connection
|
$conn = $db->connection;
|
||||||
|
|
||||||
$sth = $dbu->prepare("UPDATE notice SET content = UNHEX(?), rendered = UNHEX(?) WHERE id = ?");
|
$succ = mysqli_set_charset($conn, $charset);
|
||||||
|
|
||||||
if (PEAR::isError($sth)) {
|
if (!$succ) {
|
||||||
echo "ERROR: " . $sth->getMessage() . "\n";
|
echo "ERROR: couldn't set charset\n";
|
||||||
return;
|
$db->disconnect();
|
||||||
}
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
$sql = 'SELECT id, content, rendered FROM notice ' .
|
$result = $db->autoCommit(true);
|
||||||
'WHERE LENGTH(content) != CHAR_LENGTH(content)';
|
|
||||||
|
|
||||||
if (!empty($id)) {
|
|
||||||
$sql .= ' AND id < ' . $id;
|
|
||||||
}
|
|
||||||
|
|
||||||
$sql .= ' ORDER BY id DESC';
|
|
||||||
|
|
||||||
$rn = $dbl->query($sql);
|
|
||||||
|
|
||||||
if (PEAR::isError($rn)) {
|
|
||||||
echo "ERROR: " . $rn->getMessage() . "\n";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "Number of rows: " . $rn->numRows() . "\n";
|
|
||||||
|
|
||||||
$notice = array();
|
|
||||||
|
|
||||||
while (DB_OK == $rn->fetchInto($notice)) {
|
|
||||||
|
|
||||||
$id = ($notice[0])+0;
|
|
||||||
$content = bin2hex($notice[1]);
|
|
||||||
$rendered = bin2hex($notice[2]);
|
|
||||||
|
|
||||||
echo "$id...";
|
|
||||||
|
|
||||||
$result =& $dbu->execute($sth, array($content, $rendered, $id));
|
|
||||||
|
|
||||||
if (PEAR::isError($result)) {
|
if (PEAR::isError($result)) {
|
||||||
echo "ERROR: " . $result->getMessage() . "\n";
|
echo "ERROR: " . $result->getMessage() . "\n";
|
||||||
continue;
|
$db->disconnect();
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
$cnt = $dbu->affectedRows();
|
return $db;
|
||||||
|
}
|
||||||
|
|
||||||
if ($cnt != 1) {
|
function fixup()
|
||||||
echo "ERROR: 0 rows affected\n";
|
{
|
||||||
continue;
|
$this->fixupNotices($this->args['max_notice'],
|
||||||
|
$this->args['min_notice']);
|
||||||
|
$this->fixupProfiles();
|
||||||
|
$this->fixupGroups();
|
||||||
|
$this->fixupMessages();
|
||||||
|
}
|
||||||
|
|
||||||
|
function fixupNotices($max_id, $min_id) {
|
||||||
|
|
||||||
|
// Do a separate DB connection
|
||||||
|
|
||||||
|
$sth = $this->dbu->prepare("UPDATE notice SET content = UNHEX(?), rendered = UNHEX(?) WHERE id = ?");
|
||||||
|
|
||||||
|
if (PEAR::isError($sth)) {
|
||||||
|
echo "ERROR: " . $sth->getMessage() . "\n";
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$notice = Notice::staticGet('id', $id);
|
$sql = 'SELECT id, content, rendered FROM notice ' .
|
||||||
$notice->decache();
|
'WHERE LENGTH(content) != CHAR_LENGTH(content) '.
|
||||||
|
'AND modified < "'.$this->max_date.'" ';
|
||||||
|
|
||||||
echo "OK\n";
|
if (!empty($max_id)) {
|
||||||
|
$sql .= ' AND id <= ' . $max_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($min_id)) {
|
||||||
|
$sql .= ' AND id >= ' . $min_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql .= ' ORDER BY id DESC';
|
||||||
|
|
||||||
|
$rn = $this->dbl->query($sql);
|
||||||
|
|
||||||
|
if (PEAR::isError($rn)) {
|
||||||
|
echo "ERROR: " . $rn->getMessage() . "\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Number of rows: " . $rn->numRows() . "\n";
|
||||||
|
|
||||||
|
$notice = array();
|
||||||
|
|
||||||
|
while (DB_OK == $rn->fetchInto($notice)) {
|
||||||
|
|
||||||
|
$id = ($notice[0])+0;
|
||||||
|
$content = bin2hex($notice[1]);
|
||||||
|
$rendered = bin2hex($notice[2]);
|
||||||
|
|
||||||
|
echo "$id...";
|
||||||
|
|
||||||
|
$result =& $this->dbu->execute($sth, array($content, $rendered, $id));
|
||||||
|
|
||||||
|
if (PEAR::isError($result)) {
|
||||||
|
echo "ERROR: " . $result->getMessage() . "\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$cnt = $this->dbu->affectedRows();
|
||||||
|
|
||||||
|
if ($cnt != 1) {
|
||||||
|
echo "ERROR: 0 rows affected\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$notice = Notice::staticGet('id', $id);
|
||||||
|
$notice->decache();
|
||||||
|
$notice->free();
|
||||||
|
|
||||||
|
echo "OK\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function fixupProfiles()
|
||||||
|
{
|
||||||
|
// Do a separate DB connection
|
||||||
|
|
||||||
|
$sth = $this->dbu->prepare("UPDATE profile SET ".
|
||||||
|
"fullname = UNHEX(?),".
|
||||||
|
"location = UNHEX(?), ".
|
||||||
|
"bio = UNHEX(?) ".
|
||||||
|
"WHERE id = ?");
|
||||||
|
|
||||||
|
if (PEAR::isError($sth)) {
|
||||||
|
echo "ERROR: " . $sth->getMessage() . "\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = 'SELECT id, fullname, location, bio FROM profile ' .
|
||||||
|
'WHERE (LENGTH(fullname) != CHAR_LENGTH(fullname) '.
|
||||||
|
'OR LENGTH(location) != CHAR_LENGTH(location) '.
|
||||||
|
'OR LENGTH(bio) != CHAR_LENGTH(bio)) '.
|
||||||
|
'AND modified < "'.$this->max_date.'" '.
|
||||||
|
' ORDER BY modified DESC';
|
||||||
|
|
||||||
|
$rn = $this->dbl->query($sql);
|
||||||
|
|
||||||
|
if (PEAR::isError($rn)) {
|
||||||
|
echo "ERROR: " . $rn->getMessage() . "\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Number of rows: " . $rn->numRows() . "\n";
|
||||||
|
|
||||||
|
$profile = array();
|
||||||
|
|
||||||
|
while (DB_OK == $rn->fetchInto($profile)) {
|
||||||
|
|
||||||
|
$id = ($profile[0])+0;
|
||||||
|
$fullname = bin2hex($profile[1]);
|
||||||
|
$location = bin2hex($profile[2]);
|
||||||
|
$bio = bin2hex($profile[3]);
|
||||||
|
|
||||||
|
echo "$id...";
|
||||||
|
|
||||||
|
$result =& $this->dbu->execute($sth, array($fullname, $location, $bio, $id));
|
||||||
|
|
||||||
|
if (PEAR::isError($result)) {
|
||||||
|
echo "ERROR: " . $result->getMessage() . "\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$cnt = $this->dbu->affectedRows();
|
||||||
|
|
||||||
|
if ($cnt != 1) {
|
||||||
|
echo "ERROR: 0 rows affected\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$profile = Profile::staticGet('id', $id);
|
||||||
|
$profile->decache();
|
||||||
|
$profile->free();
|
||||||
|
|
||||||
|
echo "OK\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function fixupGroups()
|
||||||
|
{
|
||||||
|
// Do a separate DB connection
|
||||||
|
|
||||||
|
$sth = $this->dbu->prepare("UPDATE user_group SET ".
|
||||||
|
"fullname = UNHEX(?),".
|
||||||
|
"location = UNHEX(?), ".
|
||||||
|
"description = UNHEX(?) ".
|
||||||
|
"WHERE id = ?");
|
||||||
|
|
||||||
|
if (PEAR::isError($sth)) {
|
||||||
|
echo "ERROR: " . $sth->getMessage() . "\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = 'SELECT id, fullname, location, description FROM user_group ' .
|
||||||
|
'WHERE LENGTH(fullname) != CHAR_LENGTH(fullname) '.
|
||||||
|
'OR LENGTH(location) != CHAR_LENGTH(location) '.
|
||||||
|
'OR LENGTH(description) != CHAR_LENGTH(description) ';
|
||||||
|
'AND modified < "'.$this->max_date.'" '.
|
||||||
|
'ORDER BY modified DESC';
|
||||||
|
|
||||||
|
$rn = $this->dbl->query($sql);
|
||||||
|
|
||||||
|
if (PEAR::isError($rn)) {
|
||||||
|
echo "ERROR: " . $rn->getMessage() . "\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Number of rows: " . $rn->numRows() . "\n";
|
||||||
|
|
||||||
|
$user_group = array();
|
||||||
|
|
||||||
|
while (DB_OK == $rn->fetchInto($user_group)) {
|
||||||
|
|
||||||
|
$id = ($user_group[0])+0;
|
||||||
|
$fullname = bin2hex($user_group[1]);
|
||||||
|
$location = bin2hex($user_group[2]);
|
||||||
|
$description = bin2hex($user_group[3]);
|
||||||
|
|
||||||
|
echo "$id...";
|
||||||
|
|
||||||
|
$result =& $this->dbu->execute($sth, array($fullname, $location, $description, $id));
|
||||||
|
|
||||||
|
if (PEAR::isError($result)) {
|
||||||
|
echo "ERROR: " . $result->getMessage() . "\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$cnt = $this->dbu->affectedRows();
|
||||||
|
|
||||||
|
if ($cnt != 1) {
|
||||||
|
echo "ERROR: 0 rows affected\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$user_group = User_group::staticGet('id', $id);
|
||||||
|
$user_group->decache();
|
||||||
|
$user_group->free();
|
||||||
|
|
||||||
|
echo "OK\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function fixupMessages() {
|
||||||
|
|
||||||
|
// Do a separate DB connection
|
||||||
|
|
||||||
|
$sth = $this->dbu->prepare("UPDATE message SET content = UNHEX(?), rendered = UNHEX(?) WHERE id = ?");
|
||||||
|
|
||||||
|
if (PEAR::isError($sth)) {
|
||||||
|
echo "ERROR: " . $sth->getMessage() . "\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = 'SELECT id, content, rendered FROM message ' .
|
||||||
|
'WHERE LENGTH(content) != CHAR_LENGTH(content) '.
|
||||||
|
'AND modified < "'.$this->max_date.'" '.
|
||||||
|
'ORDER BY id DESC';
|
||||||
|
|
||||||
|
$rn = $this->dbl->query($sql);
|
||||||
|
|
||||||
|
if (PEAR::isError($rn)) {
|
||||||
|
echo "ERROR: " . $rn->getMessage() . "\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Number of rows: " . $rn->numRows() . "\n";
|
||||||
|
|
||||||
|
$message = array();
|
||||||
|
|
||||||
|
while (DB_OK == $rn->fetchInto($message)) {
|
||||||
|
|
||||||
|
$id = ($message[0])+0;
|
||||||
|
$content = bin2hex($message[1]);
|
||||||
|
$rendered = bin2hex($message[2]);
|
||||||
|
|
||||||
|
echo "$id...";
|
||||||
|
|
||||||
|
$result =& $this->dbu->execute($sth, array($content, $rendered, $id));
|
||||||
|
|
||||||
|
if (PEAR::isError($result)) {
|
||||||
|
echo "ERROR: " . $result->getMessage() . "\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$cnt = $this->dbu->affectedRows();
|
||||||
|
|
||||||
|
if ($cnt != 1) {
|
||||||
|
echo "ERROR: 0 rows affected\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$message = Message::staticGet('id', $id);
|
||||||
|
$message->decache();
|
||||||
|
$message->free();
|
||||||
|
|
||||||
|
echo "OK\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function doConnect($charset)
|
$max_date = ($argc > 1) ? $argv[1] : null;
|
||||||
{
|
$max_id = ($argc > 2) ? $argv[2] : null;
|
||||||
$db = DB::connect(common_config('db', 'database'),
|
$min_id = ($argc > 3) ? $argv[3] : null;
|
||||||
array('persistent' => false));
|
|
||||||
|
|
||||||
if (PEAR::isError($db)) {
|
$fixer = new UTF8FixerUpper(array('max_date' => $max_date,
|
||||||
echo "ERROR: " . $db->getMessage() . "\n";
|
'max_notice' => $max_id,
|
||||||
return NULL;
|
'min_notice' => $min_id));
|
||||||
}
|
|
||||||
|
|
||||||
$result = $db->query("SET NAMES $charset");
|
$fixer->fixup();
|
||||||
|
|
||||||
if (PEAR::isError($result)) {
|
|
||||||
echo "ERROR: " . $result->getMessage() . "\n";
|
|
||||||
$db->disconnect();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = $db->autoCommit(true);
|
|
||||||
|
|
||||||
if (PEAR::isError($result)) {
|
|
||||||
echo "ERROR: " . $result->getMessage() . "\n";
|
|
||||||
$db->disconnect();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $db;
|
|
||||||
}
|
|
||||||
|
|
||||||
$id = ($argc > 1) ? $argv[1] : null;
|
|
||||||
|
|
||||||
fixup_utf8($id);
|
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
* daemon names.
|
* daemon names.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
# Abort if called from a web server
|
# Abort if called from a web server
|
||||||
if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) {
|
if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) {
|
||||||
print "This script must be run from the command line\n";
|
print "This script must be run from the command line\n";
|
||||||
|
@ -51,5 +50,4 @@ echo "ombqueuehandler.php ";
|
||||||
echo "twitterqueuehandler.php ";
|
echo "twitterqueuehandler.php ";
|
||||||
echo "facebookqueuehandler.php ";
|
echo "facebookqueuehandler.php ";
|
||||||
echo "pingqueuehandler.php ";
|
echo "pingqueuehandler.php ";
|
||||||
echo "inboxqueuehandler.php ";
|
|
||||||
echo "smsqueuehandler.php ";
|
echo "smsqueuehandler.php ";
|
||||||
|
|
|
@ -1,69 +0,0 @@
|
||||||
#!/usr/bin/env php
|
|
||||||
<?php
|
|
||||||
/*
|
|
||||||
* Laconica - a distributed open-source microblogging tool
|
|
||||||
* Copyright (C) 2008,2009 Control Yourself, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Abort if called from a web server
|
|
||||||
|
|
||||||
if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) {
|
|
||||||
print "This script must be run from the command line\n";
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
|
|
||||||
define('LACONICA', true);
|
|
||||||
|
|
||||||
require_once(INSTALLDIR . '/lib/common.php');
|
|
||||||
require_once(INSTALLDIR . '/lib/queuehandler.php');
|
|
||||||
|
|
||||||
set_error_handler('common_error_handler');
|
|
||||||
|
|
||||||
class InboxQueueHandler extends QueueHandler
|
|
||||||
{
|
|
||||||
function transport()
|
|
||||||
{
|
|
||||||
return 'inbox';
|
|
||||||
}
|
|
||||||
|
|
||||||
function start() {
|
|
||||||
$this->log(LOG_INFO, "INITIALIZE");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function handle_notice($notice)
|
|
||||||
{
|
|
||||||
$this->log(LOG_INFO, "Distributing notice to inboxes for $notice->id");
|
|
||||||
$notice->addToInboxes();
|
|
||||||
$notice->blowSubsCache();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function finish() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ini_set("max_execution_time", "0");
|
|
||||||
ini_set("max_input_time", "0");
|
|
||||||
set_time_limit(0);
|
|
||||||
mb_internal_encoding('UTF-8');
|
|
||||||
|
|
||||||
$id = ($argc > 1) ? $argv[1] : null;
|
|
||||||
|
|
||||||
$handler = new InboxQueueHandler($id);
|
|
||||||
|
|
||||||
$handler->runOnce();
|
|
|
@ -1,70 +0,0 @@
|
||||||
#!/usr/bin/env php
|
|
||||||
<?php
|
|
||||||
/*
|
|
||||||
* Laconica - a distributed open-source microblogging tool
|
|
||||||
* Copyright (C) 2008,2009 Control Yourself, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Abort if called from a web server
|
|
||||||
|
|
||||||
if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) {
|
|
||||||
print "This script must be run from the command line\n";
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
|
|
||||||
define('LACONICA', true);
|
|
||||||
|
|
||||||
require_once(INSTALLDIR . '/lib/common.php');
|
|
||||||
require_once(INSTALLDIR . '/lib/queuehandler.php');
|
|
||||||
|
|
||||||
set_error_handler('common_error_handler');
|
|
||||||
|
|
||||||
class MemcachedQueueHandler extends QueueHandler
|
|
||||||
{
|
|
||||||
function transport()
|
|
||||||
{
|
|
||||||
return 'memcache';
|
|
||||||
}
|
|
||||||
|
|
||||||
function start() {
|
|
||||||
$this->log(LOG_INFO, "INITIALIZE");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function handle_notice($notice)
|
|
||||||
{
|
|
||||||
// XXX: fork here
|
|
||||||
$this->log(LOG_INFO, "Blowing memcached for $notice->id");
|
|
||||||
$notice->blowCaches();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function finish() {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ini_set("max_execution_time", "0");
|
|
||||||
ini_set("max_input_time", "0");
|
|
||||||
set_time_limit(0);
|
|
||||||
mb_internal_encoding('UTF-8');
|
|
||||||
|
|
||||||
$id = ($argc > 1) ? $argv[1] : null;
|
|
||||||
|
|
||||||
$handler = new MemcachedQueueHandler($id);
|
|
||||||
|
|
||||||
$handler->runOnce();
|
|
|
@ -24,8 +24,7 @@ SDIR=`dirname $0`
|
||||||
DIR=`php $SDIR/getpiddir.php`
|
DIR=`php $SDIR/getpiddir.php`
|
||||||
|
|
||||||
for f in jabberhandler ombhandler publichandler smshandler pinghandler \
|
for f in jabberhandler ombhandler publichandler smshandler pinghandler \
|
||||||
xmppconfirmhandler xmppdaemon twitterhandler facebookhandler \
|
xmppconfirmhandler xmppdaemon twitterhandler facebookhandler; do
|
||||||
memcachehandler inboxhandler twitterstatusfetcher; do
|
|
||||||
|
|
||||||
FILES="$DIR/$f.*.pid"
|
FILES="$DIR/$f.*.pid"
|
||||||
for ff in "$FILES" ; do
|
for ff in "$FILES" ; do
|
||||||
|
|
Loading…
Reference in New Issue
Block a user