Merge branch '0.8.x' into notice-search-no-results
This commit is contained in:
commit
71dc910a53
@ -63,6 +63,7 @@ class ConversationAction extends Action
|
|||||||
if (empty($this->id)) {
|
if (empty($this->id)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
$this->id = $this->id+0;
|
||||||
$this->page = $this->trimmed('page');
|
$this->page = $this->trimmed('page');
|
||||||
if (empty($this->page)) {
|
if (empty($this->page)) {
|
||||||
$this->page = 1;
|
$this->page = 1;
|
||||||
@ -106,18 +107,10 @@ class ConversationAction extends Action
|
|||||||
|
|
||||||
function showContent()
|
function showContent()
|
||||||
{
|
{
|
||||||
// FIXME this needs to be a tree, not a list
|
|
||||||
|
|
||||||
$qry = 'SELECT * FROM notice WHERE conversation = %s ';
|
|
||||||
|
|
||||||
$offset = ($this->page-1) * NOTICES_PER_PAGE;
|
$offset = ($this->page-1) * NOTICES_PER_PAGE;
|
||||||
$limit = NOTICES_PER_PAGE + 1;
|
$limit = NOTICES_PER_PAGE + 1;
|
||||||
|
|
||||||
$txt = sprintf($qry, $this->id);
|
$notices = Notice::conversationStream($this->id, $offset, $limit);
|
||||||
|
|
||||||
$notices = Notice::getStream($txt,
|
|
||||||
'notice:conversation:'.$this->id,
|
|
||||||
$offset, $limit);
|
|
||||||
|
|
||||||
$ct = new ConversationTree($notices, $this);
|
$ct = new ConversationTree($notices, $this);
|
||||||
|
|
||||||
@ -126,7 +119,6 @@ class ConversationAction extends Action
|
|||||||
$this->pagination($this->page > 1, $cnt > NOTICES_PER_PAGE,
|
$this->pagination($this->page > 1, $cnt > NOTICES_PER_PAGE,
|
||||||
$this->page, 'conversation', array('id' => $this->id));
|
$this->page, 'conversation', array('id' => $this->id));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -21,20 +21,40 @@ if (!defined('LACONICA')) { exit(1); }
|
|||||||
|
|
||||||
require_once(INSTALLDIR.'/actions/shownotice.php');
|
require_once(INSTALLDIR.'/actions/shownotice.php');
|
||||||
|
|
||||||
class FileAction extends ShowNoticeAction
|
class FileAction extends Action
|
||||||
{
|
{
|
||||||
function showPage() {
|
var $id = null;
|
||||||
$source_url = common_local_url('file', array('notice' => $this->notice->id));
|
var $filerec = null;
|
||||||
$query = "select file_redirection.url as url from file join file_redirection on file.id = file_redirection.file_id where file.url = '$source_url'";
|
|
||||||
$file = new File_redirection;
|
function prepare($args)
|
||||||
$file->query($query);
|
{
|
||||||
$file->fetch();
|
parent::prepare($args);
|
||||||
if (empty($file->url)) {
|
$this->id = $this->trimmed('notice');
|
||||||
die('nothing attached here');
|
if (empty($this->id)) {
|
||||||
} else {
|
$this->clientError(_('No notice id'));
|
||||||
header("Location: {$file->url}");
|
|
||||||
die();
|
|
||||||
}
|
}
|
||||||
|
$notice = Notice::staticGet('id', $this->id);
|
||||||
|
if (empty($notice)) {
|
||||||
|
$this->clientError(_('No notice'));
|
||||||
|
}
|
||||||
|
$atts = $notice->attachments();
|
||||||
|
if (empty($atts)) {
|
||||||
|
$this->clientError(_('No attachments'));
|
||||||
|
}
|
||||||
|
foreach ($atts as $att) {
|
||||||
|
if (!empty($att->filename)) {
|
||||||
|
$this->filerec = $att;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (empty($this->filerec)) {
|
||||||
|
$this->clientError(_('No uploaded attachments'));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handle() {
|
||||||
|
common_redirect($this->filerec->url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,7 +238,6 @@ class GroupDesignSettingsAction extends DesignSettingsAction
|
|||||||
$design->sidebarcolor = $sbcolor->intValue();
|
$design->sidebarcolor = $sbcolor->intValue();
|
||||||
$design->textcolor = $tcolor->intValue();
|
$design->textcolor = $tcolor->intValue();
|
||||||
$design->linkcolor = $lcolor->intValue();
|
$design->linkcolor = $lcolor->intValue();
|
||||||
$design->backgroundimage = $filepath;
|
|
||||||
|
|
||||||
$design->setDisposition($on, $off, $tile);
|
$design->setDisposition($on, $off, $tile);
|
||||||
|
|
||||||
@ -263,7 +262,6 @@ class GroupDesignSettingsAction extends DesignSettingsAction
|
|||||||
$design->sidebarcolor = $sbcolor->intValue();
|
$design->sidebarcolor = $sbcolor->intValue();
|
||||||
$design->textcolor = $tcolor->intValue();
|
$design->textcolor = $tcolor->intValue();
|
||||||
$design->linkcolor = $lcolor->intValue();
|
$design->linkcolor = $lcolor->intValue();
|
||||||
$design->backgroundimage = $filepath;
|
|
||||||
|
|
||||||
$design->setDisposition($on, $off, $tile);
|
$design->setDisposition($on, $off, $tile);
|
||||||
|
|
||||||
|
@ -236,6 +236,7 @@ class NewnoticeAction extends Action
|
|||||||
$this->deleteFile($filename);
|
$this->deleteFile($filename);
|
||||||
$this->clientError(_('Max notice size is 140 chars, including attachment URL.'));
|
$this->clientError(_('Max notice size is 140 chars, including attachment URL.'));
|
||||||
}
|
}
|
||||||
|
$fileRecord = $this->rememberFile($filename, $mimetype, $short_fileurl);
|
||||||
}
|
}
|
||||||
|
|
||||||
$notice = Notice::saveNew($user->id, $content_shortened, 'web', 1,
|
$notice = Notice::saveNew($user->id, $content_shortened, 'web', 1,
|
||||||
@ -249,7 +250,7 @@ class NewnoticeAction extends Action
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isset($mimetype)) {
|
if (isset($mimetype)) {
|
||||||
$this->attachFile($notice, $filename, $mimetype, $short_fileurl);
|
$this->attachFile($notice, $fileRecord);
|
||||||
}
|
}
|
||||||
|
|
||||||
common_broadcast_notice($notice);
|
common_broadcast_notice($notice);
|
||||||
@ -304,12 +305,12 @@ class NewnoticeAction extends Action
|
|||||||
@unlink($filepath);
|
@unlink($filepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
function attachFile($notice, $filename, $mimetype, $short)
|
function rememberFile($filename, $mimetype, $short)
|
||||||
{
|
{
|
||||||
$file = new File;
|
$file = new File;
|
||||||
$file->filename = $filename;
|
$file->filename = $filename;
|
||||||
|
|
||||||
$file->url = common_local_url('file', array('notice' => $notice->id));
|
$file->url = File::url($filename);
|
||||||
|
|
||||||
$filepath = File::path($filename);
|
$filepath = File::path($filename);
|
||||||
|
|
||||||
@ -324,26 +325,35 @@ class NewnoticeAction extends Action
|
|||||||
$this->clientError(_('There was a database error while saving your file. Please try again.'));
|
$this->clientError(_('There was a database error while saving your file. Please try again.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$file_redir = new File_redirection;
|
$this->maybeAddRedir($file_id, $short);
|
||||||
$file_redir->url = File::url($filename);
|
|
||||||
$file_redir->file_id = $file_id;
|
|
||||||
|
|
||||||
$result = $file_redir->insert();
|
return $file;
|
||||||
|
}
|
||||||
|
|
||||||
if (!$result) {
|
function maybeAddRedir($file_id, $url)
|
||||||
common_log_db_error($file_redir, "INSERT", __FILE__);
|
{
|
||||||
$this->clientError(_('There was a database error while saving your file. Please try again.'));
|
$file_redir = File_redirection::staticGet('url', $url);
|
||||||
|
|
||||||
|
if (empty($file_redir)) {
|
||||||
|
$file_redir = new File_redirection;
|
||||||
|
$file_redir->url = $url;
|
||||||
|
$file_redir->file_id = $file_id;
|
||||||
|
|
||||||
|
$result = $file_redir->insert();
|
||||||
|
|
||||||
|
if (!$result) {
|
||||||
|
common_log_db_error($file_redir, "INSERT", __FILE__);
|
||||||
|
$this->clientError(_('There was a database error while saving your file. Please try again.'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$f2p = new File_to_post;
|
function attachFile($notice, $filerec)
|
||||||
$f2p->file_id = $file_id;
|
{
|
||||||
$f2p->post_id = $notice->id;
|
File_to_post::processNew($filerec->id, $notice->id);
|
||||||
$f2p->insert();
|
|
||||||
|
|
||||||
if (!$result) {
|
$this->maybeAddRedir($filerec->id,
|
||||||
common_log_db_error($f2p, "INSERT", __FILE__);
|
common_local_url('file', array('notice' => $notice->id)));
|
||||||
$this->clientError(_('There was a database error while saving your file. Please try again.'));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,6 +35,10 @@ require_once INSTALLDIR.'/lib/publicgroupnav.php';
|
|||||||
require_once INSTALLDIR.'/lib/noticelist.php';
|
require_once INSTALLDIR.'/lib/noticelist.php';
|
||||||
require_once INSTALLDIR.'/lib/feedlist.php';
|
require_once INSTALLDIR.'/lib/feedlist.php';
|
||||||
|
|
||||||
|
// Farther than any human will go
|
||||||
|
|
||||||
|
define('MAX_PUBLIC_PAGE', 100);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action for displaying the public stream
|
* Action for displaying the public stream
|
||||||
*
|
*
|
||||||
@ -74,6 +78,10 @@ class PublicAction extends Action
|
|||||||
parent::prepare($args);
|
parent::prepare($args);
|
||||||
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
|
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
|
||||||
|
|
||||||
|
if ($this->page > MAX_PUBLIC_PAGE) {
|
||||||
|
$this->clientError(sprintf(_("Beyond the page limit (%s)"), MAX_PUBLIC_PAGE));
|
||||||
|
}
|
||||||
|
|
||||||
common_set_returnto($this->selfUrl());
|
common_set_returnto($this->selfUrl());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -191,10 +191,21 @@ class ShowfavoritesAction extends CurrentUserDesignAction
|
|||||||
|
|
||||||
function showContent()
|
function showContent()
|
||||||
{
|
{
|
||||||
$notice = $this->user->favoriteNotices(($this->page-1)*NOTICES_PER_PAGE,
|
$cur = common_current_user();
|
||||||
NOTICES_PER_PAGE + 1);
|
|
||||||
|
|
||||||
if (!$notice) {
|
if (!empty($cur) && $cur->id == $this->user->id) {
|
||||||
|
|
||||||
|
// Show imported/gateway notices as well as local if
|
||||||
|
// the user is looking at his own favorites
|
||||||
|
|
||||||
|
$notice = $this->user->favoriteNotices(($this->page-1)*NOTICES_PER_PAGE,
|
||||||
|
NOTICES_PER_PAGE + 1, true);
|
||||||
|
} else {
|
||||||
|
$notice = $this->user->favoriteNotices(($this->page-1)*NOTICES_PER_PAGE,
|
||||||
|
NOTICES_PER_PAGE + 1, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($notice)) {
|
||||||
$this->serverError(_('Could not retrieve favorite notices.'));
|
$this->serverError(_('Could not retrieve favorite notices.'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,11 @@ class TwitapifavoritesAction extends TwitterapiAction
|
|||||||
$since_id = (int)$this->arg('since_id', 0);
|
$since_id = (int)$this->arg('since_id', 0);
|
||||||
$since = $this->arg('since');
|
$since = $this->arg('since');
|
||||||
|
|
||||||
$notice = $user->favoriteNotices(($page-1)*$count, $count);
|
if (!empty($this->auth_user) && $this->auth_user->id == $user->id) {
|
||||||
|
$notice = $user->favoriteNotices(($page-1)*$count, $count, true);
|
||||||
|
} else {
|
||||||
|
$notice = $user->favoriteNotices(($page-1)*$count, $count, false);
|
||||||
|
}
|
||||||
|
|
||||||
switch($apidata['content-type']) {
|
switch($apidata['content-type']) {
|
||||||
case 'xml':
|
case 'xml':
|
||||||
|
@ -75,8 +75,8 @@ class TwitapistatusesAction extends TwitterapiAction
|
|||||||
{
|
{
|
||||||
parent::handle($args);
|
parent::handle($args);
|
||||||
|
|
||||||
|
$this->auth_user = $apidata['user'];
|
||||||
$user = $this->get_user($apidata['api_arg'], $apidata);
|
$user = $this->get_user($apidata['api_arg'], $apidata);
|
||||||
$this->auth_user = $user;
|
|
||||||
|
|
||||||
if (empty($user)) {
|
if (empty($user)) {
|
||||||
$this->clientError(_('No such user!'), 404,
|
$this->clientError(_('No such user!'), 404,
|
||||||
@ -100,8 +100,13 @@ class TwitapistatusesAction extends TwitterapiAction
|
|||||||
$since_id = (int)$this->arg('since_id', 0);
|
$since_id = (int)$this->arg('since_id', 0);
|
||||||
$since = $this->arg('since');
|
$since = $this->arg('since');
|
||||||
|
|
||||||
$notice = $user->noticesWithFriends(($page-1)*$count,
|
if (!empty($this->auth_user) && $this->auth_user->id == $user->id) {
|
||||||
$count, $since_id, $max_id,$since);
|
$notice = $user->noticeInbox(($page-1)*$count,
|
||||||
|
$count, $since_id, $max_id, $since);
|
||||||
|
} else {
|
||||||
|
$notice = $user->noticesWithFriends(($page-1)*$count,
|
||||||
|
$count, $since_id, $max_id, $since);
|
||||||
|
}
|
||||||
|
|
||||||
switch($apidata['content-type']) {
|
switch($apidata['content-type']) {
|
||||||
case 'xml':
|
case 'xml':
|
||||||
|
@ -149,7 +149,6 @@ class UserDesignSettingsAction extends DesignSettingsAction
|
|||||||
$design->sidebarcolor = $sbcolor->intValue();
|
$design->sidebarcolor = $sbcolor->intValue();
|
||||||
$design->textcolor = $tcolor->intValue();
|
$design->textcolor = $tcolor->intValue();
|
||||||
$design->linkcolor = $lcolor->intValue();
|
$design->linkcolor = $lcolor->intValue();
|
||||||
$design->backgroundimage = $filepath;
|
|
||||||
|
|
||||||
$design->setDisposition($on, $off, $tile);
|
$design->setDisposition($on, $off, $tile);
|
||||||
|
|
||||||
@ -174,7 +173,6 @@ class UserDesignSettingsAction extends DesignSettingsAction
|
|||||||
$design->sidebarcolor = $sbcolor->intValue();
|
$design->sidebarcolor = $sbcolor->intValue();
|
||||||
$design->textcolor = $tcolor->intValue();
|
$design->textcolor = $tcolor->intValue();
|
||||||
$design->linkcolor = $lcolor->intValue();
|
$design->linkcolor = $lcolor->intValue();
|
||||||
$design->backgroundimage = $filepath;
|
|
||||||
|
|
||||||
$design->setDisposition($on, $off, $tile);
|
$design->setDisposition($on, $off, $tile);
|
||||||
|
|
||||||
|
@ -37,52 +37,62 @@ class Fave extends Memcached_DataObject
|
|||||||
return Memcached_DataObject::pkeyGet('Fave', $kv);
|
return Memcached_DataObject::pkeyGet('Fave', $kv);
|
||||||
}
|
}
|
||||||
|
|
||||||
function stream($user_id, $offset=0, $limit=NOTICES_PER_PAGE)
|
function stream($user_id, $offset=0, $limit=NOTICES_PER_PAGE, $own=false)
|
||||||
{
|
{
|
||||||
$ids = Notice::stream(array('Fave', '_streamDirect'),
|
$ids = Notice::stream(array('Fave', '_streamDirect'),
|
||||||
array($user_id),
|
array($user_id, $own),
|
||||||
'fave:ids_by_user:'.$user_id,
|
($own) ? 'fave:ids_by_user_own:'.$user_id :
|
||||||
|
'fave:by_user:'.$user_id,
|
||||||
$offset, $limit);
|
$offset, $limit);
|
||||||
return $ids;
|
return $ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _streamDirect($user_id, $offset, $limit, $since_id, $max_id, $since)
|
function _streamDirect($user_id, $own, $offset, $limit, $since_id, $max_id, $since)
|
||||||
{
|
{
|
||||||
$fav = new Fave();
|
$fav = new Fave();
|
||||||
|
$qry = null;
|
||||||
|
|
||||||
$fav->user_id = $user_id;
|
if ($own) {
|
||||||
|
$qry = 'SELECT fave.* FROM fave ';
|
||||||
$fav->selectAdd();
|
$qry .= 'WHERE fave.user_id = ' . $user_id . ' ';
|
||||||
$fav->selectAdd('notice_id');
|
} else {
|
||||||
|
$qry = 'SELECT fave.* FROM fave ';
|
||||||
|
$qry .= 'INNER JOIN notice ON fave.notice_id = notice.id ';
|
||||||
|
$qry .= 'WHERE fave.user_id = ' . $user_id . ' ';
|
||||||
|
$qry .= 'AND notice.is_local != ' . NOTICE_GATEWAY . ' ';
|
||||||
|
}
|
||||||
|
|
||||||
if ($since_id != 0) {
|
if ($since_id != 0) {
|
||||||
$fav->whereAdd('notice_id > ' . $since_id);
|
$qry .= 'AND notice_id > ' . $since_id . ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($max_id != 0) {
|
if ($max_id != 0) {
|
||||||
$fav->whereAdd('notice_id <= ' . $max_id);
|
$qry .= 'AND notice_id <= ' . $max_id . ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_null($since)) {
|
if (!is_null($since)) {
|
||||||
$fav->whereAdd('modified > \'' . date('Y-m-d H:i:s', $since) . '\'');
|
$qry .= 'AND modified > \'' . date('Y-m-d H:i:s', $since) . '\' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: we sort by fave time, not by notice time!
|
// NOTE: we sort by fave time, not by notice time!
|
||||||
|
|
||||||
$fav->orderBy('modified DESC');
|
$qry .= 'ORDER BY modified DESC ';
|
||||||
|
|
||||||
if (!is_null($offset)) {
|
if (!is_null($offset)) {
|
||||||
$fav->limit($offset, $limit);
|
$qry .= "LIMIT $offset, $limit";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$fav->query($qry);
|
||||||
|
|
||||||
$ids = array();
|
$ids = array();
|
||||||
|
|
||||||
if ($fav->find()) {
|
while ($fav->fetch()) {
|
||||||
while ($fav->fetch()) {
|
$ids[] = $fav->notice_id;
|
||||||
$ids[] = $fav->notice_id;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$fav->free();
|
||||||
|
unset($fav);
|
||||||
|
|
||||||
return $ids;
|
return $ids;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,9 +91,10 @@ class File extends Memcached_DataObject
|
|||||||
$given_url = File_redirection::_canonUrl($given_url);
|
$given_url = File_redirection::_canonUrl($given_url);
|
||||||
if (empty($given_url)) return -1; // error, no url to process
|
if (empty($given_url)) return -1; // error, no url to process
|
||||||
$file = File::staticGet('url', $given_url);
|
$file = File::staticGet('url', $given_url);
|
||||||
if (empty($file->id)) {
|
if (empty($file)) {
|
||||||
$file_redir = File_redirection::staticGet('url', $given_url);
|
$file_redir = File_redirection::staticGet('url', $given_url);
|
||||||
if (empty($file_redir->id)) {
|
if (empty($file_redir)) {
|
||||||
|
common_debug("processNew() '$given_url' not a known redirect.\n");
|
||||||
$redir_data = File_redirection::where($given_url);
|
$redir_data = File_redirection::where($given_url);
|
||||||
$redir_url = $redir_data['url'];
|
$redir_url = $redir_data['url'];
|
||||||
if ($redir_url === $given_url) {
|
if ($redir_url === $given_url) {
|
||||||
|
@ -66,21 +66,17 @@ class File_redirection extends Memcached_DataObject
|
|||||||
|
|
||||||
// let's see if we know this...
|
// let's see if we know this...
|
||||||
$a = File::staticGet('url', $short_url);
|
$a = File::staticGet('url', $short_url);
|
||||||
if (empty($a->id)) {
|
|
||||||
$b = File_redirection::staticGet('url', $short_url);
|
if (!empty($a)) {
|
||||||
if (empty($b->id)) {
|
|
||||||
// we'll have to figure it out
|
|
||||||
} else {
|
|
||||||
// this is a redirect to $b->file_id
|
|
||||||
$a = File::staticGet($b->file_id);
|
|
||||||
$url = $a->url;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// this is a direct link to $a->url
|
// this is a direct link to $a->url
|
||||||
$url = $a->url;
|
return $a->url;
|
||||||
}
|
} else {
|
||||||
if (isset($url)) {
|
$b = File_redirection::staticGet('url', $short_url);
|
||||||
return $url;
|
if (!empty($b)) {
|
||||||
|
// this is a redirect to $b->file_id
|
||||||
|
$a = File::staticGet('id', $b->file_id);
|
||||||
|
return $a->url;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$curlh = File_redirection::_commonCurl($short_url, $redirs);
|
$curlh = File_redirection::_commonCurl($short_url, $redirs);
|
||||||
@ -118,28 +114,22 @@ class File_redirection extends Memcached_DataObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
function makeShort($long_url) {
|
function makeShort($long_url) {
|
||||||
$long_url = File_redirection::_canonUrl($long_url);
|
|
||||||
// do we already know this long_url and have a short redirection for it?
|
|
||||||
$file = new File;
|
|
||||||
$file_redir = new File_redirection;
|
|
||||||
$file->url = $long_url;
|
|
||||||
$file->joinAdd($file_redir);
|
|
||||||
$file->selectAdd('length(file_redirection.url) as len');
|
|
||||||
$file->limit(1);
|
|
||||||
$file->orderBy('len');
|
|
||||||
$file->find(true);
|
|
||||||
if (!empty($file->url) && (strlen($file->url) < strlen($long_url))) {
|
|
||||||
return $file->url;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if yet unknown, we must find a short url according to user settings
|
$canon = File_redirection::_canonUrl($long_url);
|
||||||
$short_url = File_redirection::_userMakeShort($long_url, common_current_user());
|
|
||||||
return $short_url;
|
$short_url = File_redirection::_userMakeShort($canon);
|
||||||
|
|
||||||
|
// Did we get one? Is it shorter?
|
||||||
|
if (!empty($short_url) && mb_strlen($short_url) < mb_strlen($long_url)) {
|
||||||
|
return $short_url;
|
||||||
|
} else {
|
||||||
|
return $long_url;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function _userMakeShort($long_url, $user) {
|
function _userMakeShort($long_url) {
|
||||||
$short_url = common_shorten_url($long_url);
|
$short_url = common_shorten_url($long_url);
|
||||||
if ($short_url) {
|
if (!empty($short_url) && $short_url != $long_url) {
|
||||||
$short_url = (string)$short_url;
|
$short_url = (string)$short_url;
|
||||||
// store it
|
// store it
|
||||||
$file = File::staticGet('url', $long_url);
|
$file = File::staticGet('url', $long_url);
|
||||||
@ -162,7 +152,7 @@ class File_redirection extends Memcached_DataObject
|
|||||||
}
|
}
|
||||||
return $short_url;
|
return $short_url;
|
||||||
}
|
}
|
||||||
return $long_url;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _canonUrl($in_url, $default_scheme = 'http://') {
|
function _canonUrl($in_url, $default_scheme = 'http://') {
|
||||||
|
@ -25,7 +25,7 @@ require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
|
|||||||
* Table Definition for file_to_post
|
* Table Definition for file_to_post
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class File_to_post extends Memcached_DataObject
|
class File_to_post extends Memcached_DataObject
|
||||||
{
|
{
|
||||||
###START_AUTOCODE
|
###START_AUTOCODE
|
||||||
/* the code below is auto generated do not remove the above tag */
|
/* the code below is auto generated do not remove the above tag */
|
||||||
@ -44,17 +44,27 @@ class File_to_post extends Memcached_DataObject
|
|||||||
function processNew($file_id, $notice_id) {
|
function processNew($file_id, $notice_id) {
|
||||||
static $seen = array();
|
static $seen = array();
|
||||||
if (empty($seen[$notice_id]) || !in_array($file_id, $seen[$notice_id])) {
|
if (empty($seen[$notice_id]) || !in_array($file_id, $seen[$notice_id])) {
|
||||||
$f2p = new File_to_post;
|
|
||||||
$f2p->file_id = $file_id;
|
$f2p = File_to_post::pkeyGet(array('post_id' => $notice_id,
|
||||||
$f2p->post_id = $notice_id;
|
'file_id' => $file_id));
|
||||||
$f2p->insert();
|
if (empty($f2p)) {
|
||||||
|
$f2p = new File_to_post;
|
||||||
|
$f2p->file_id = $file_id;
|
||||||
|
$f2p->post_id = $notice_id;
|
||||||
|
$f2p->insert();
|
||||||
|
}
|
||||||
|
|
||||||
if (empty($seen[$notice_id])) {
|
if (empty($seen[$notice_id])) {
|
||||||
$seen[$notice_id] = array($file_id);
|
$seen[$notice_id] = array($file_id);
|
||||||
} else {
|
} else {
|
||||||
$seen[$notice_id][] = $file_id;
|
$seen[$notice_id][] = $file_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function &pkeyGet($kv)
|
||||||
|
{
|
||||||
|
return Memcached_DataObject::pkeyGet('File_to_post', $kv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,42 +4,41 @@
|
|||||||
*/
|
*/
|
||||||
require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
|
require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
|
||||||
|
|
||||||
class Foreign_user extends Memcached_DataObject
|
class Foreign_user extends Memcached_DataObject
|
||||||
{
|
{
|
||||||
###START_AUTOCODE
|
###START_AUTOCODE
|
||||||
/* the code below is auto generated do not remove the above tag */
|
/* the code below is auto generated do not remove the above tag */
|
||||||
|
|
||||||
public $__table = 'foreign_user'; // table name
|
public $__table = 'foreign_user'; // table name
|
||||||
public $id; // int(4) primary_key not_null
|
public $id; // bigint(8) primary_key not_null
|
||||||
public $service; // int(4) primary_key not_null
|
public $service; // int(4) primary_key not_null
|
||||||
public $uri; // varchar(255) unique_key not_null
|
public $uri; // varchar(255) unique_key not_null
|
||||||
public $nickname; // varchar(255)
|
public $nickname; // varchar(255)
|
||||||
public $created; // datetime() not_null
|
public $created; // datetime() not_null
|
||||||
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
|
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
|
||||||
|
|
||||||
/* Static get */
|
/* Static get */
|
||||||
function staticGet($k,$v=null)
|
function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Foreign_user',$k,$v); }
|
||||||
{ return Memcached_DataObject::staticGet('Foreign_user',$k,$v); }
|
|
||||||
|
|
||||||
/* 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
|
||||||
|
|
||||||
// XXX: This only returns a 1->1 single obj mapping. Change? Or make
|
// XXX: This only returns a 1->1 single obj mapping. Change? Or make
|
||||||
// a getForeignUsers() that returns more than one? --Zach
|
// a getForeignUsers() that returns more than one? --Zach
|
||||||
static function getForeignUser($id, $service) {
|
static function getForeignUser($id, $service) {
|
||||||
$fuser = new Foreign_user();
|
$fuser = new Foreign_user();
|
||||||
$fuser->whereAdd("service = $service");
|
$fuser->whereAdd("service = $service");
|
||||||
$fuser->whereAdd("id = $id");
|
$fuser->whereAdd("id = $id");
|
||||||
$fuser->limit(1);
|
$fuser->limit(1);
|
||||||
|
|
||||||
if ($fuser->find()) {
|
if ($fuser->find()) {
|
||||||
$fuser->fetch();
|
$fuser->fetch();
|
||||||
return $fuser;
|
return $fuser;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateKeys(&$orig)
|
function updateKeys(&$orig)
|
||||||
{
|
{
|
||||||
$parts = array();
|
$parts = array();
|
||||||
@ -68,5 +67,4 @@ class Foreign_user extends Memcached_DataObject
|
|||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,14 @@ class Group_inbox extends Memcached_DataObject
|
|||||||
public $created; // datetime() not_null
|
public $created; // datetime() not_null
|
||||||
|
|
||||||
/* Static get */
|
/* Static get */
|
||||||
|
|
||||||
function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Group_inbox',$k,$v); }
|
function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Group_inbox',$k,$v); }
|
||||||
|
|
||||||
/* 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 &pkeyGet($kv)
|
||||||
|
{
|
||||||
|
return Memcached_DataObject::pkeyGet('Group_inbox', $kv);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -331,6 +331,20 @@ class Notice extends Memcached_DataObject
|
|||||||
return $n_attachments;
|
return $n_attachments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function attachments() {
|
||||||
|
// XXX: cache this
|
||||||
|
$att = array();
|
||||||
|
$f2p = new File_to_post;
|
||||||
|
$f2p->post_id = $this->id;
|
||||||
|
if ($f2p->find()) {
|
||||||
|
while ($f2p->fetch()) {
|
||||||
|
$f = File::staticGet($f2p->file_id);
|
||||||
|
$att[] = clone($f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $att;
|
||||||
|
}
|
||||||
|
|
||||||
function blowCaches($blowLast=false)
|
function blowCaches($blowLast=false)
|
||||||
{
|
{
|
||||||
$this->blowSubsCache($blowLast);
|
$this->blowSubsCache($blowLast);
|
||||||
@ -339,6 +353,19 @@ class Notice extends Memcached_DataObject
|
|||||||
$this->blowPublicCache($blowLast);
|
$this->blowPublicCache($blowLast);
|
||||||
$this->blowTagCache($blowLast);
|
$this->blowTagCache($blowLast);
|
||||||
$this->blowGroupCache($blowLast);
|
$this->blowGroupCache($blowLast);
|
||||||
|
$this->blowConversationCache($blowLast);
|
||||||
|
}
|
||||||
|
|
||||||
|
function blowConversationCache($blowLast=false)
|
||||||
|
{
|
||||||
|
$cache = common_memcache();
|
||||||
|
if ($cache) {
|
||||||
|
$ck = common_cache_key('notice:conversation_ids:'.$this->conversation);
|
||||||
|
$cache->delete($ck);
|
||||||
|
if ($blowLast) {
|
||||||
|
$cache->delete($ck.';last');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function blowGroupCache($blowLast=false)
|
function blowGroupCache($blowLast=false)
|
||||||
@ -471,8 +498,10 @@ class Notice extends Memcached_DataObject
|
|||||||
if ($fave->find()) {
|
if ($fave->find()) {
|
||||||
while ($fave->fetch()) {
|
while ($fave->fetch()) {
|
||||||
$cache->delete(common_cache_key('fave:ids_by_user:'.$fave->user_id));
|
$cache->delete(common_cache_key('fave:ids_by_user:'.$fave->user_id));
|
||||||
|
$cache->delete(common_cache_key('fave:by_user_own:'.$fave->user_id));
|
||||||
if ($blowLast) {
|
if ($blowLast) {
|
||||||
$cache->delete(common_cache_key('fave:ids_by_user:'.$fave->user_id.';last'));
|
$cache->delete(common_cache_key('fave:ids_by_user:'.$fave->user_id.';last'));
|
||||||
|
$cache->delete(common_cache_key('fave:by_user_own:'.$fave->user_id.';last'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -675,7 +704,10 @@ class Notice extends Memcached_DataObject
|
|||||||
if (!empty($cache)) {
|
if (!empty($cache)) {
|
||||||
$notices = array();
|
$notices = array();
|
||||||
foreach ($ids as $id) {
|
foreach ($ids as $id) {
|
||||||
$notices[] = Notice::staticGet('id', $id);
|
$n = Notice::staticGet('id', $id);
|
||||||
|
if (!empty($n)) {
|
||||||
|
$notices[] = $n;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return new ArrayWrapper($notices);
|
return new ArrayWrapper($notices);
|
||||||
} else {
|
} else {
|
||||||
@ -744,29 +776,116 @@ class Notice extends Memcached_DataObject
|
|||||||
return $ids;
|
return $ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function conversationStream($id, $offset=0, $limit=20, $since_id=0, $max_id=0, $since=null)
|
||||||
|
{
|
||||||
|
$ids = Notice::stream(array('Notice', '_conversationStreamDirect'),
|
||||||
|
array($id),
|
||||||
|
'notice:conversation_ids:'.$id,
|
||||||
|
$offset, $limit, $since_id, $max_id, $since);
|
||||||
|
|
||||||
|
return Notice::getStreamByIds($ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _conversationStreamDirect($id, $offset=0, $limit=20, $since_id=0, $max_id=0, $since=null)
|
||||||
|
{
|
||||||
|
$notice = new Notice();
|
||||||
|
|
||||||
|
$notice->selectAdd(); // clears it
|
||||||
|
$notice->selectAdd('id');
|
||||||
|
|
||||||
|
$notice->whereAdd('conversation = '.$id);
|
||||||
|
|
||||||
|
$notice->orderBy('id DESC');
|
||||||
|
|
||||||
|
if (!is_null($offset)) {
|
||||||
|
$notice->limit($offset, $limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($since_id != 0) {
|
||||||
|
$notice->whereAdd('id > ' . $since_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($max_id != 0) {
|
||||||
|
$notice->whereAdd('id <= ' . $max_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_null($since)) {
|
||||||
|
$notice->whereAdd('created > \'' . date('Y-m-d H:i:s', $since) . '\'');
|
||||||
|
}
|
||||||
|
|
||||||
|
$ids = array();
|
||||||
|
|
||||||
|
if ($notice->find()) {
|
||||||
|
while ($notice->fetch()) {
|
||||||
|
$ids[] = $notice->id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$notice->free();
|
||||||
|
$notice = NULL;
|
||||||
|
|
||||||
|
return $ids;
|
||||||
|
}
|
||||||
|
|
||||||
function addToInboxes()
|
function addToInboxes()
|
||||||
{
|
{
|
||||||
$enabled = common_config('inboxes', 'enabled');
|
$enabled = common_config('inboxes', 'enabled');
|
||||||
|
|
||||||
if ($enabled === true || $enabled === 'transitional') {
|
if ($enabled === true || $enabled === 'transitional') {
|
||||||
$inbox = new Notice_inbox();
|
|
||||||
$UT = common_config('db','type')=='pgsql'?'"user"':'user';
|
$users = $this->getSubscribedUsers();
|
||||||
$qry = 'INSERT INTO notice_inbox (user_id, notice_id, created) ' .
|
|
||||||
"SELECT $UT.id, " . $this->id . ", '" . $this->created . "' " .
|
// FIXME: kind of ignoring 'transitional'...
|
||||||
"FROM $UT JOIN subscription ON $UT.id = subscription.subscriber " .
|
// we'll probably stop supporting inboxless mode
|
||||||
'WHERE subscription.subscribed = ' . $this->profile_id . ' ' .
|
// in 0.9.x
|
||||||
'AND NOT EXISTS (SELECT user_id, notice_id ' .
|
|
||||||
'FROM notice_inbox ' .
|
foreach ($users as $id) {
|
||||||
"WHERE user_id = $UT.id " .
|
$this->addToUserInbox($id, NOTICE_INBOX_SOURCE_SUB);
|
||||||
'AND notice_id = ' . $this->id . ' )';
|
|
||||||
if ($enabled === 'transitional') {
|
|
||||||
$qry .= " AND $UT.inboxed = 1";
|
|
||||||
}
|
}
|
||||||
$inbox->query($qry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getSubscribedUsers()
|
||||||
|
{
|
||||||
|
$user = new User();
|
||||||
|
|
||||||
|
$qry =
|
||||||
|
'SELECT id ' .
|
||||||
|
'FROM user JOIN subscription '.
|
||||||
|
'ON user.id = subscription.subscriber ' .
|
||||||
|
'WHERE subscription.subscribed = %d ';
|
||||||
|
|
||||||
|
$user->query(sprintf($qry, $this->profile_id));
|
||||||
|
|
||||||
|
$ids = array();
|
||||||
|
|
||||||
|
while ($user->fetch()) {
|
||||||
|
$ids[] = $user->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
$user->free();
|
||||||
|
|
||||||
|
return $ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
function addToUserInbox($user_id, $source)
|
||||||
|
{
|
||||||
|
$inbox = Notice_inbox::pkeyGet(array('user_id' => $user_id,
|
||||||
|
'notice_id' => $this->id));
|
||||||
|
if (empty($inbox)) {
|
||||||
|
$inbox = new Notice_inbox();
|
||||||
|
$inbox->user_id = $user_id;
|
||||||
|
$inbox->notice_id = $this->id;
|
||||||
|
$inbox->source = $source;
|
||||||
|
$inbox->created = $this->created;
|
||||||
|
return $inbox->insert();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
function saveGroups()
|
function saveGroups()
|
||||||
{
|
{
|
||||||
$enabled = common_config('inboxes', 'enabled');
|
$enabled = common_config('inboxes', 'enabled');
|
||||||
@ -805,13 +924,7 @@ class Notice extends Memcached_DataObject
|
|||||||
|
|
||||||
if ($profile->isMember($group)) {
|
if ($profile->isMember($group)) {
|
||||||
|
|
||||||
$gi = new Group_inbox();
|
$result = $this->addToGroupInbox($group);
|
||||||
|
|
||||||
$gi->group_id = $group->id;
|
|
||||||
$gi->notice_id = $this->id;
|
|
||||||
$gi->created = common_sql_now();
|
|
||||||
|
|
||||||
$result = $gi->insert();
|
|
||||||
|
|
||||||
if (!$result) {
|
if (!$result) {
|
||||||
common_log_db_error($gi, 'INSERT', __FILE__);
|
common_log_db_error($gi, 'INSERT', __FILE__);
|
||||||
@ -819,27 +932,37 @@ class Notice extends Memcached_DataObject
|
|||||||
|
|
||||||
// FIXME: do this in an offline daemon
|
// FIXME: do this in an offline daemon
|
||||||
|
|
||||||
$this->addToGroupInboxes($group);
|
$this->addToGroupMemberInboxes($group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function addToGroupInboxes($group)
|
function addToGroupInbox($group)
|
||||||
{
|
{
|
||||||
$inbox = new Notice_inbox();
|
$gi = Group_inbox::pkeyGet(array('group_id' => $group->id,
|
||||||
$UT = common_config('db','type')=='pgsql'?'"user"':'user';
|
'notice_id' => $this->id));
|
||||||
$qry = 'INSERT INTO notice_inbox (user_id, notice_id, created, source) ' .
|
|
||||||
"SELECT $UT.id, " . $this->id . ", '" . $this->created . "', " . NOTICE_INBOX_SOURCE_GROUP . " " .
|
if (empty($gi)) {
|
||||||
"FROM $UT JOIN group_member ON $UT.id = group_member.profile_id " .
|
|
||||||
'WHERE group_member.group_id = ' . $group->id . ' ' .
|
$gi = new Group_inbox();
|
||||||
'AND NOT EXISTS (SELECT user_id, notice_id ' .
|
|
||||||
'FROM notice_inbox ' .
|
$gi->group_id = $group->id;
|
||||||
"WHERE user_id = $UT.id " .
|
$gi->notice_id = $this->id;
|
||||||
'AND notice_id = ' . $this->id . ' )';
|
$gi->created = $this->created;
|
||||||
if ($enabled === 'transitional') {
|
|
||||||
$qry .= " AND $UT.inboxed = 1";
|
return $gi->insert();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function addToGroupMemberInboxes($group)
|
||||||
|
{
|
||||||
|
$users = $group->getUserMembers();
|
||||||
|
|
||||||
|
foreach ($users as $id) {
|
||||||
|
$this->addToUserInbox($id, NOTICE_INBOX_SOURCE_GROUP);
|
||||||
}
|
}
|
||||||
$result = $inbox->query($qry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveReplies()
|
function saveReplies()
|
||||||
|
@ -27,6 +27,7 @@ define('INBOX_CACHE_WINDOW', 101);
|
|||||||
|
|
||||||
define('NOTICE_INBOX_SOURCE_SUB', 1);
|
define('NOTICE_INBOX_SOURCE_SUB', 1);
|
||||||
define('NOTICE_INBOX_SOURCE_GROUP', 2);
|
define('NOTICE_INBOX_SOURCE_GROUP', 2);
|
||||||
|
define('NOTICE_INBOX_SOURCE_REPLY', 3);
|
||||||
define('NOTICE_INBOX_SOURCE_GATEWAY', -1);
|
define('NOTICE_INBOX_SOURCE_GATEWAY', -1);
|
||||||
|
|
||||||
class Notice_inbox extends Memcached_DataObject
|
class Notice_inbox extends Memcached_DataObject
|
||||||
|
@ -289,4 +289,52 @@ class Profile extends Memcached_DataObject
|
|||||||
return Avatar::defaultImage($size);
|
return Avatar::defaultImage($size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getSubscriptions($offset=0, $limit=null)
|
||||||
|
{
|
||||||
|
$qry =
|
||||||
|
'SELECT profile.* ' .
|
||||||
|
'FROM profile JOIN subscription ' .
|
||||||
|
'ON profile.id = subscription.subscribed ' .
|
||||||
|
'WHERE subscription.subscriber = %d ' .
|
||||||
|
'AND subscription.subscribed != subscription.subscriber ' .
|
||||||
|
'ORDER BY subscription.created DESC ';
|
||||||
|
|
||||||
|
if (common_config('db','type') == 'pgsql') {
|
||||||
|
$qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
|
||||||
|
} else {
|
||||||
|
$qry .= ' LIMIT ' . $offset . ', ' . $limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$profile = new Profile();
|
||||||
|
|
||||||
|
$profile->query(sprintf($qry, $this->id));
|
||||||
|
|
||||||
|
return $profile;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSubscribers($offset=0, $limit=null)
|
||||||
|
{
|
||||||
|
$qry =
|
||||||
|
'SELECT profile.* ' .
|
||||||
|
'FROM profile JOIN subscription ' .
|
||||||
|
'ON profile.id = subscription.subscriber ' .
|
||||||
|
'WHERE subscription.subscribed = %d ' .
|
||||||
|
'AND subscription.subscribed != subscription.subscriber ' .
|
||||||
|
'ORDER BY subscription.created DESC ';
|
||||||
|
|
||||||
|
if ($offset) {
|
||||||
|
if (common_config('db','type') == 'pgsql') {
|
||||||
|
$qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
|
||||||
|
} else {
|
||||||
|
$qry .= ' LIMIT ' . $offset . ', ' . $limit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$profile = new Profile();
|
||||||
|
|
||||||
|
$cnt = $profile->query(sprintf($qry, $this->id));
|
||||||
|
|
||||||
|
return $profile;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -424,9 +424,9 @@ class User extends Memcached_DataObject
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function favoriteNotices($offset=0, $limit=NOTICES_PER_PAGE)
|
function favoriteNotices($offset=0, $limit=NOTICES_PER_PAGE, $own=false)
|
||||||
{
|
{
|
||||||
$ids = Fave::stream($this->id, $offset, $limit);
|
$ids = Fave::stream($this->id, $offset, $limit, $own);
|
||||||
return Notice::getStreamByIds($ids);
|
return Notice::getStreamByIds($ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -600,50 +600,16 @@ class User extends Memcached_DataObject
|
|||||||
|
|
||||||
function getSubscriptions($offset=0, $limit=null)
|
function getSubscriptions($offset=0, $limit=null)
|
||||||
{
|
{
|
||||||
$qry =
|
$profile = $this->getProfile();
|
||||||
'SELECT profile.* ' .
|
assert(!empty($profile));
|
||||||
'FROM profile JOIN subscription ' .
|
return $profile->getSubscriptions($offset, $limit);
|
||||||
'ON profile.id = subscription.subscribed ' .
|
|
||||||
'WHERE subscription.subscriber = %d ' .
|
|
||||||
'AND subscription.subscribed != subscription.subscriber ' .
|
|
||||||
'ORDER BY subscription.created DESC ';
|
|
||||||
|
|
||||||
if (common_config('db','type') == 'pgsql') {
|
|
||||||
$qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
|
|
||||||
} else {
|
|
||||||
$qry .= ' LIMIT ' . $offset . ', ' . $limit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$profile = new Profile();
|
|
||||||
|
|
||||||
$profile->query(sprintf($qry, $this->id));
|
|
||||||
|
|
||||||
return $profile;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSubscribers($offset=0, $limit=null)
|
function getSubscribers($offset=0, $limit=null)
|
||||||
{
|
{
|
||||||
$qry =
|
$profile = $this->getProfile();
|
||||||
'SELECT profile.* ' .
|
assert(!empty($profile));
|
||||||
'FROM profile JOIN subscription ' .
|
return $profile->getSubscribers($offset, $limit);
|
||||||
'ON profile.id = subscription.subscriber ' .
|
|
||||||
'WHERE subscription.subscribed = %d ' .
|
|
||||||
'AND subscription.subscribed != subscription.subscriber ' .
|
|
||||||
'ORDER BY subscription.created DESC ';
|
|
||||||
|
|
||||||
if ($offset) {
|
|
||||||
if (common_config('db','type') == 'pgsql') {
|
|
||||||
$qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
|
|
||||||
} else {
|
|
||||||
$qry .= ' LIMIT ' . $offset . ', ' . $limit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$profile = new Profile();
|
|
||||||
|
|
||||||
$cnt = $profile->query(sprintf($qry, $this->id));
|
|
||||||
|
|
||||||
return $profile;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTaggedSubscribers($tag, $offset=0, $limit=null)
|
function getTaggedSubscribers($tag, $offset=0, $limit=null)
|
||||||
|
@ -246,4 +246,28 @@ class User_group extends Memcached_DataObject
|
|||||||
return Design::staticGet('id', $this->design_id);
|
return Design::staticGet('id', $this->design_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getUserMembers()
|
||||||
|
{
|
||||||
|
// XXX: cache this
|
||||||
|
|
||||||
|
$user = new User();
|
||||||
|
|
||||||
|
$qry =
|
||||||
|
'SELECT id ' .
|
||||||
|
'FROM user JOIN group_member '.
|
||||||
|
'ON user.id = group_member.profile_id ' .
|
||||||
|
'WHERE group_member.group_id = %d ';
|
||||||
|
|
||||||
|
$user->query(sprintf($qry, $this->id));
|
||||||
|
|
||||||
|
$ids = array();
|
||||||
|
|
||||||
|
while ($user->fetch()) {
|
||||||
|
$ids[] = $user->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
$user->free();
|
||||||
|
|
||||||
|
return $ids;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
109
db/074to080.sql
Normal file
109
db/074to080.sql
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
alter table user
|
||||||
|
add column design_id integer comment 'id of a design' references design(id),
|
||||||
|
add column viewdesigns tinyint default 1 comment 'whether to view user-provided designs';
|
||||||
|
|
||||||
|
alter table notice add column
|
||||||
|
conversation integer comment 'id of root notice in this conversation' references notice (id),
|
||||||
|
add index notice_conversation_idx (conversation);
|
||||||
|
|
||||||
|
alter table foreign_user
|
||||||
|
modify column id bigint not null comment 'unique numeric key on foreign service';
|
||||||
|
|
||||||
|
alter table foreign_link
|
||||||
|
modify column foreign_id bigint unsigned comment 'link to user on foreign service, if exists';
|
||||||
|
|
||||||
|
alter table user_group
|
||||||
|
add column design_id integer comment 'id of a design' references design(id);
|
||||||
|
|
||||||
|
create table file (
|
||||||
|
id integer primary key auto_increment,
|
||||||
|
url varchar(255) comment 'destination URL after following redirections',
|
||||||
|
mimetype varchar(50) comment 'mime type of resource',
|
||||||
|
size integer comment 'size of resource when available',
|
||||||
|
title varchar(255) comment 'title of resource when available',
|
||||||
|
date integer(11) comment 'date of resource according to http query',
|
||||||
|
protected integer(1) comment 'true when URL is private (needs login)',
|
||||||
|
filename varchar(255) comment 'if a local file, name of the file',
|
||||||
|
modified timestamp comment 'date this record was modified',
|
||||||
|
|
||||||
|
unique(url)
|
||||||
|
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci;
|
||||||
|
|
||||||
|
create table file_oembed (
|
||||||
|
file_id integer primary key comment 'oEmbed for that URL/file' references file (id),
|
||||||
|
version varchar(20) comment 'oEmbed spec. version',
|
||||||
|
type varchar(20) comment 'oEmbed type: photo, video, link, rich',
|
||||||
|
provider varchar(50) comment 'name of this oEmbed provider',
|
||||||
|
provider_url varchar(255) comment 'URL of this oEmbed provider',
|
||||||
|
width integer comment 'width of oEmbed resource when available',
|
||||||
|
height integer comment 'height of oEmbed resource when available',
|
||||||
|
html text comment 'html representation of this oEmbed resource when applicable',
|
||||||
|
title varchar(255) comment 'title of oEmbed resource when available',
|
||||||
|
author_name varchar(50) comment 'author name for this oEmbed resource',
|
||||||
|
author_url varchar(255) comment 'author URL for this oEmbed resource',
|
||||||
|
url varchar(255) comment 'URL for this oEmbed resource when applicable (photo, link)',
|
||||||
|
modified timestamp comment 'date this record was modified'
|
||||||
|
|
||||||
|
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci;
|
||||||
|
|
||||||
|
create table file_redirection (
|
||||||
|
|
||||||
|
url varchar(255) primary key comment 'short URL (or any other kind of redirect) for file (id)',
|
||||||
|
file_id integer comment 'short URL for what URL/file' references file (id),
|
||||||
|
redirections integer comment 'redirect count',
|
||||||
|
httpcode integer comment 'HTTP status code (20x, 30x, etc.)',
|
||||||
|
modified timestamp comment 'date this record was modified'
|
||||||
|
|
||||||
|
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
|
||||||
|
|
||||||
|
create table file_thumbnail (
|
||||||
|
|
||||||
|
file_id integer primary key comment 'thumbnail for what URL/file' references file (id),
|
||||||
|
url varchar(255) comment 'URL of thumbnail',
|
||||||
|
width integer comment 'width of thumbnail',
|
||||||
|
height integer comment 'height of thumbnail',
|
||||||
|
modified timestamp comment 'date this record was modified',
|
||||||
|
|
||||||
|
unique(url)
|
||||||
|
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
|
||||||
|
|
||||||
|
create table file_to_post (
|
||||||
|
|
||||||
|
file_id integer comment 'id of URL/file' references file (id),
|
||||||
|
post_id integer comment 'id of the notice it belongs to' references notice (id),
|
||||||
|
modified timestamp comment 'date this record was modified',
|
||||||
|
|
||||||
|
constraint primary key (file_id, post_id)
|
||||||
|
|
||||||
|
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
|
||||||
|
|
||||||
|
create table design (
|
||||||
|
id integer primary key auto_increment comment 'design ID',
|
||||||
|
backgroundcolor integer comment 'main background color',
|
||||||
|
contentcolor integer comment 'content area background color',
|
||||||
|
sidebarcolor integer comment 'sidebar background color',
|
||||||
|
textcolor integer comment 'text color',
|
||||||
|
linkcolor integer comment 'link color',
|
||||||
|
backgroundimage varchar(255) comment 'background image, if any',
|
||||||
|
disposition tinyint default 1 comment 'bit 1 = hide background image, bit 2 = display background image, bit 4 = tile background image'
|
||||||
|
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
|
||||||
|
|
||||||
|
create table group_block (
|
||||||
|
group_id integer not null comment 'group profile is blocked from' references user_group (id),
|
||||||
|
blocked integer not null comment 'profile that is blocked' references profile (id),
|
||||||
|
blocker integer not null comment 'user making the block' references user (id),
|
||||||
|
modified timestamp comment 'date of blocking',
|
||||||
|
|
||||||
|
constraint primary key (group_id, blocked)
|
||||||
|
|
||||||
|
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
|
||||||
|
|
||||||
|
create table group_alias (
|
||||||
|
|
||||||
|
alias varchar(64) primary key comment 'additional nickname for the group',
|
||||||
|
group_id integer not null comment 'group profile is blocked from' references user_group (id),
|
||||||
|
modified timestamp comment 'date alias was created',
|
||||||
|
|
||||||
|
index group_alias_group_id_idx (group_id)
|
||||||
|
|
||||||
|
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
|
@ -277,7 +277,7 @@ create table foreign_service (
|
|||||||
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
|
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
|
||||||
|
|
||||||
create table foreign_user (
|
create table foreign_user (
|
||||||
id int not null comment 'unique numeric key on foreign service',
|
id bigint not null comment 'unique numeric key on foreign service',
|
||||||
service int not null comment 'foreign key to service' references foreign_service(id),
|
service int not null comment 'foreign key to service' references foreign_service(id),
|
||||||
uri varchar(255) not null unique key comment 'identifying URI',
|
uri varchar(255) not null unique key comment 'identifying URI',
|
||||||
nickname varchar(255) comment 'nickname on foreign service',
|
nickname varchar(255) comment 'nickname on foreign service',
|
||||||
|
@ -48,7 +48,14 @@ function handleError($error)
|
|||||||
$logmsg .= " : ". $error->getDebugInfo();
|
$logmsg .= " : ". $error->getDebugInfo();
|
||||||
}
|
}
|
||||||
common_log(LOG_ERR, $logmsg);
|
common_log(LOG_ERR, $logmsg);
|
||||||
if ($error instanceof DB_DataObject_Error) {
|
if(common_config('site', 'logdebug')) {
|
||||||
|
$bt = $error->getBacktrace();
|
||||||
|
foreach ($bt as $line) {
|
||||||
|
common_log(LOG_ERR, $line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($error instanceof DB_DataObject_Error ||
|
||||||
|
$error instanceof DB_Error) {
|
||||||
$msg = sprintf(_('The database for %s isn\'t responding correctly, '.
|
$msg = sprintf(_('The database for %s isn\'t responding correctly, '.
|
||||||
'so the site won\'t work properly. '.
|
'so the site won\'t work properly. '.
|
||||||
'The site admins probably know about the problem, '.
|
'The site admins probably know about the problem, '.
|
||||||
|
@ -89,11 +89,10 @@ $(document).ready(function() {
|
|||||||
$('body').css({'background-image':'none'});
|
$('body').css({'background-image':'none'});
|
||||||
});
|
});
|
||||||
$('#design_background-image_on').focus(function() {
|
$('#design_background-image_on').focus(function() {
|
||||||
var bis = $('#design_background-image_onoff img')[0].src;
|
$('body').css({'background-image':'url('+$('#design_background-image_onoff img')[0].src+')'});
|
||||||
$('body').css({'background-image':'url('+bis+')'});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#design_background-image_repeat').click(function() {
|
$('#design_background-image_repeat').click(function() {
|
||||||
($(this)[0].checked) ? $('body').css({'background-repeat':'repeat'}) : $('body').css({'background-repeat':'no-repeat'});
|
($(this)[0].checked) ? $('body').css({'background-repeat':'repeat'}) : $('body').css({'background-repeat':'no-repeat'});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
19
js/util.js
19
js/util.js
@ -222,6 +222,7 @@ $(document).ready(function(){
|
|||||||
}
|
}
|
||||||
$("#notice_data-text").val("");
|
$("#notice_data-text").val("");
|
||||||
$("#notice_data-attach").val("");
|
$("#notice_data-attach").val("");
|
||||||
|
$('#notice_data-attach_selected').remove();
|
||||||
counter();
|
counter();
|
||||||
}
|
}
|
||||||
$("#form_notice").removeClass("processing");
|
$("#form_notice").removeClass("processing");
|
||||||
@ -233,6 +234,7 @@ $(document).ready(function(){
|
|||||||
$("#form_notice").each(addAjaxHidden);
|
$("#form_notice").each(addAjaxHidden);
|
||||||
NoticeReply();
|
NoticeReply();
|
||||||
NoticeAttachments();
|
NoticeAttachments();
|
||||||
|
NoticeDataAttach();
|
||||||
});
|
});
|
||||||
|
|
||||||
function NoticeReply() {
|
function NoticeReply() {
|
||||||
@ -280,13 +282,13 @@ function NoticeAttachments() {
|
|||||||
timeout : 0
|
timeout : 0
|
||||||
};
|
};
|
||||||
|
|
||||||
$('a.attachment').click(function() {
|
$('#content .notice a.attachment').click(function() {
|
||||||
$().jOverlay({url: $('address .url')[0].href+'/attachment/' + ($(this).attr('id').substring('attachment'.length + 1)) + '/ajax'});
|
$().jOverlay({url: $('address .url')[0].href+'/attachment/' + ($(this).attr('id').substring('attachment'.length + 1)) + '/ajax'});
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
var t;
|
var t;
|
||||||
$("body:not(#shownotice) a.thumbnail").hover(
|
$("body:not(#shownotice) #content .notice a.thumbnail").hover(
|
||||||
function() {
|
function() {
|
||||||
var anchor = $(this);
|
var anchor = $(this);
|
||||||
$("a.thumbnail").children('img').hide();
|
$("a.thumbnail").children('img').hide();
|
||||||
@ -310,3 +312,16 @@ function NoticeAttachments() {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function NoticeDataAttach() {
|
||||||
|
NDA = $('#notice_data-attach');
|
||||||
|
NDA.change(function() {
|
||||||
|
S = '<div id="notice_data-attach_selected" class="success"><code>'+$(this).val()+'</code> <button>×</button></div>';
|
||||||
|
NDAS = $('#notice_data-attach_selected');
|
||||||
|
(NDAS.length > 0) ? NDAS.replaceWith(S) : $('#form_notice').append(S);
|
||||||
|
$('#notice_data-attach_selected button').click(function(){
|
||||||
|
$('#notice_data-attach_selected').remove();
|
||||||
|
NDA.val('');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@ -82,7 +82,8 @@ class AttachmentList extends Widget
|
|||||||
$atts = new File;
|
$atts = new File;
|
||||||
$att = $atts->getAttachments($this->notice->id);
|
$att = $atts->getAttachments($this->notice->id);
|
||||||
if (empty($att)) return 0;
|
if (empty($att)) return 0;
|
||||||
$this->out->elementStart('dl', array('id' =>'attachments'));
|
$this->out->elementStart('dl', array('id' =>'attachments',
|
||||||
|
'class' => 'entry-content'));
|
||||||
$this->out->element('dt', null, _('Attachments'));
|
$this->out->element('dt', null, _('Attachments'));
|
||||||
$this->out->elementStart('dd');
|
$this->out->elementStart('dd');
|
||||||
$this->out->elementStart('ol', array('class' => 'attachments'));
|
$this->out->elementStart('ol', array('class' => 'attachments'));
|
||||||
@ -249,10 +250,13 @@ class Attachment extends AttachmentListItem
|
|||||||
$this->out->elementStart('div', 'entry-title');
|
$this->out->elementStart('div', 'entry-title');
|
||||||
$this->out->elementStart('a', $this->linkAttr());
|
$this->out->elementStart('a', $this->linkAttr());
|
||||||
$this->out->element('span', null, $this->linkTitle());
|
$this->out->element('span', null, $this->linkTitle());
|
||||||
$this->showRepresentation();
|
|
||||||
$this->out->elementEnd('a');
|
$this->out->elementEnd('a');
|
||||||
$this->out->elementEnd('div');
|
$this->out->elementEnd('div');
|
||||||
|
|
||||||
|
$this->out->elementStart('div', 'entry-content');
|
||||||
|
$this->showRepresentation();
|
||||||
|
$this->out->elementEnd('div');
|
||||||
|
|
||||||
if (!empty($this->oembed->author_name) || !empty($this->oembed->provider)) {
|
if (!empty($this->oembed->author_name) || !empty($this->oembed->provider)) {
|
||||||
$this->out->elementStart('div', array('id' => 'oembed_info',
|
$this->out->elementStart('div', array('id' => 'oembed_info',
|
||||||
'class' => 'entry-content'));
|
'class' => 'entry-content'));
|
||||||
|
@ -95,9 +95,9 @@ $config =
|
|||||||
'server' => $_server,
|
'server' => $_server,
|
||||||
'theme' => 'default',
|
'theme' => 'default',
|
||||||
'design' =>
|
'design' =>
|
||||||
array('backgroundcolor' => '#F0F2F5',
|
array('backgroundcolor' => '#CEE1E9',
|
||||||
'contentcolor' => '#FFFFFF',
|
'contentcolor' => '#FFFFFF',
|
||||||
'sidebarcolor' => '#CEE1E9',
|
'sidebarcolor' => '#C8D1D5',
|
||||||
'textcolor' => '#000000',
|
'textcolor' => '#000000',
|
||||||
'linkcolor' => '#002E6E',
|
'linkcolor' => '#002E6E',
|
||||||
'backgroundimage' => null,
|
'backgroundimage' => null,
|
||||||
@ -125,7 +125,13 @@ $config =
|
|||||||
array('appname' => 'laconica', # for syslog
|
array('appname' => 'laconica', # for syslog
|
||||||
'priority' => 'debug'), # XXX: currently ignored
|
'priority' => 'debug'), # XXX: currently ignored
|
||||||
'queue' =>
|
'queue' =>
|
||||||
array('enabled' => false),
|
array('enabled' => false,
|
||||||
|
'subsystem' => 'db', # default to database, or 'stomp'
|
||||||
|
'stomp_server' => null,
|
||||||
|
'queue_basename' => 'laconica',
|
||||||
|
'stomp_username' => null,
|
||||||
|
'stomp_password' => null,
|
||||||
|
),
|
||||||
'license' =>
|
'license' =>
|
||||||
array('url' => 'http://creativecommons.org/licenses/by/3.0/',
|
array('url' => 'http://creativecommons.org/licenses/by/3.0/',
|
||||||
'title' => 'Creative Commons Attribution 3.0',
|
'title' => 'Creative Commons Attribution 3.0',
|
||||||
|
@ -132,13 +132,13 @@ class DesignSettingsAction extends AccountSettingsAction
|
|||||||
_('Off'));
|
_('Off'));
|
||||||
$this->element('p', 'form_guide', _('Turn background image on or off.'));
|
$this->element('p', 'form_guide', _('Turn background image on or off.'));
|
||||||
$this->elementEnd('li');
|
$this->elementEnd('li');
|
||||||
}
|
|
||||||
|
|
||||||
$this->elementStart('li');
|
$this->elementStart('li');
|
||||||
$this->checkbox('design_background-image_repeat',
|
$this->checkbox('design_background-image_repeat',
|
||||||
_('Tile background image'),
|
_('Tile background image'),
|
||||||
($design->disposition & BACKGROUND_TILE) ? true : false );
|
($design->disposition & BACKGROUND_TILE) ? true : false );
|
||||||
$this->elementEnd('li');
|
$this->elementEnd('li');
|
||||||
|
}
|
||||||
|
|
||||||
$this->elementEnd('ul');
|
$this->elementEnd('ul');
|
||||||
$this->elementEnd('fieldset');
|
$this->elementEnd('fieldset');
|
||||||
@ -388,7 +388,11 @@ class DesignSettingsAction extends AccountSettingsAction
|
|||||||
|
|
||||||
$original = clone($design);
|
$original = clone($design);
|
||||||
$design->backgroundimage = $filename;
|
$design->backgroundimage = $filename;
|
||||||
|
|
||||||
|
// default to on, no tile
|
||||||
|
|
||||||
$design->setDisposition(true, false, false);
|
$design->setDisposition(true, false, false);
|
||||||
|
|
||||||
$result = $design->update($original);
|
$result = $design->update($original);
|
||||||
|
|
||||||
if ($result === false) {
|
if ($result === false) {
|
||||||
|
@ -72,7 +72,8 @@ class ImageFile
|
|||||||
break;
|
break;
|
||||||
case UPLOAD_ERR_INI_SIZE:
|
case UPLOAD_ERR_INI_SIZE:
|
||||||
case UPLOAD_ERR_FORM_SIZE:
|
case UPLOAD_ERR_FORM_SIZE:
|
||||||
throw new Exception(sprintf(_('That file is too big. The maximum file size is %d.'), $this->maxFileSize()));
|
throw new Exception(sprintf(_('That file is too big. The maximum file size is %d.'),
|
||||||
|
ImageFile::maxFileSize()));
|
||||||
return;
|
return;
|
||||||
case UPLOAD_ERR_PARTIAL:
|
case UPLOAD_ERR_PARTIAL:
|
||||||
@unlink($_FILES[$param]['tmp_name']);
|
@unlink($_FILES[$param]['tmp_name']);
|
||||||
|
@ -432,7 +432,7 @@ class NoticeListItem extends Widget
|
|||||||
$this->out->elementStart('dl', 'response');
|
$this->out->elementStart('dl', 'response');
|
||||||
$this->out->element('dt', null, _('To'));
|
$this->out->element('dt', null, _('To'));
|
||||||
$this->out->elementStart('dd');
|
$this->out->elementStart('dd');
|
||||||
$this->out->element('a', array('href' => $convurl),
|
$this->out->element('a', array('href' => $convurl.'#notice-'.$this->notice->id),
|
||||||
_('in context'));
|
_('in context'));
|
||||||
$this->out->elementEnd('dd');
|
$this->out->elementEnd('dd');
|
||||||
$this->out->elementEnd('dl');
|
$this->out->elementEnd('dl');
|
||||||
|
@ -112,12 +112,21 @@ class QueueHandler extends Daemon
|
|||||||
}
|
}
|
||||||
|
|
||||||
function stomp_dispatch() {
|
function stomp_dispatch() {
|
||||||
require("Stomp.php");
|
|
||||||
$con = new Stomp(common_config('queue','stomp_server'));
|
// use an external message queue system via STOMP
|
||||||
if (!$con->connect()) {
|
require_once("Stomp.php");
|
||||||
|
|
||||||
|
$server = common_config('queue','stomp_server');
|
||||||
|
$username = common_config('queue', 'stomp_username');
|
||||||
|
$password = common_config('queue', 'stomp_password');
|
||||||
|
|
||||||
|
$con = new Stomp($server);
|
||||||
|
|
||||||
|
if (!$con->connect($username, $password)) {
|
||||||
$this->log(LOG_ERR, 'Failed to connect to queue server');
|
$this->log(LOG_ERR, 'Failed to connect to queue server');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$queue_basename = common_config('queue','queue_basename');
|
$queue_basename = common_config('queue','queue_basename');
|
||||||
// subscribe to the relevant queue (format: basename-transport)
|
// subscribe to the relevant queue (format: basename-transport)
|
||||||
$con->subscribe('/queue/'.$queue_basename.'-'.$this->transport());
|
$con->subscribe('/queue/'.$queue_basename.'-'.$this->transport());
|
||||||
|
181
lib/util.php
181
lib/util.php
@ -497,6 +497,22 @@ function common_linkify($url) {
|
|||||||
|
|
||||||
$attrs = array('href' => $longurl, 'rel' => 'external');
|
$attrs = array('href' => $longurl, 'rel' => 'external');
|
||||||
|
|
||||||
|
$is_attachment = false;
|
||||||
|
$attachment_id = null;
|
||||||
|
$has_thumb = false;
|
||||||
|
|
||||||
|
// Check to see whether there's a filename associated with this URL.
|
||||||
|
// If there is, it's an upload and qualifies as an attachment
|
||||||
|
|
||||||
|
$localfile = File::staticGet('url', $longurl);
|
||||||
|
|
||||||
|
if (!empty($localfile)) {
|
||||||
|
if (isset($localfile->filename)) {
|
||||||
|
$is_attachment = true;
|
||||||
|
$attachment_id = $localfile->id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// if this URL is an attachment, then we set class='attachment' and id='attahcment-ID'
|
// if this URL is an attachment, then we set class='attachment' and id='attahcment-ID'
|
||||||
// where ID is the id of the attachment for the given URL.
|
// where ID is the id of the attachment for the given URL.
|
||||||
//
|
//
|
||||||
@ -504,24 +520,35 @@ function common_linkify($url) {
|
|||||||
// we're currently picking up oembeds only.
|
// we're currently picking up oembeds only.
|
||||||
// I think the best option is another file_view table in the db
|
// I think the best option is another file_view table in the db
|
||||||
// and associated dbobject.
|
// and associated dbobject.
|
||||||
|
|
||||||
$query = "select file_oembed.file_id as file_id from file join file_oembed on file.id = file_oembed.file_id where file.url='$longurl'";
|
$query = "select file_oembed.file_id as file_id from file join file_oembed on file.id = file_oembed.file_id where file.url='$longurl'";
|
||||||
$file = new File;
|
$file = new File;
|
||||||
$file->query($query);
|
$file->query($query);
|
||||||
$file->fetch();
|
$file->fetch();
|
||||||
|
|
||||||
if (!empty($file->file_id)) {
|
if (!empty($file->file_id)) {
|
||||||
|
$is_attachment = true;
|
||||||
|
$attachment_id = $file->file_id;
|
||||||
|
|
||||||
$query = "select file_thumbnail.file_id as file_id from file join file_thumbnail on file.id = file_thumbnail.file_id where file.url='$longurl'";
|
$query = "select file_thumbnail.file_id as file_id from file join file_thumbnail on file.id = file_thumbnail.file_id where file.url='$longurl'";
|
||||||
$file2 = new File;
|
$file2 = new File;
|
||||||
$file2->query($query);
|
$file2->query($query);
|
||||||
$file2->fetch();
|
$file2->fetch();
|
||||||
|
|
||||||
if (empty($file2->file_id)) {
|
if (!empty($file2)) {
|
||||||
$attrs['class'] = 'attachment';
|
$has_thumb = true;
|
||||||
} else {
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add clippy
|
||||||
|
if ($is_attachment) {
|
||||||
|
$attrs['class'] = 'attachment';
|
||||||
|
if ($has_thumb) {
|
||||||
$attrs['class'] = 'attachment thumbnail';
|
$attrs['class'] = 'attachment thumbnail';
|
||||||
}
|
}
|
||||||
$attrs['id'] = "attachment-{$file->file_id}";
|
$attrs['id'] = "attachment-{$attachment_id}";
|
||||||
}
|
}
|
||||||
|
|
||||||
return XMLStringer::estring('a', $attrs, $display);
|
return XMLStringer::estring('a', $attrs, $display);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -826,89 +853,91 @@ function common_broadcast_notice($notice, $remote=false)
|
|||||||
|
|
||||||
function common_enqueue_notice($notice)
|
function common_enqueue_notice($notice)
|
||||||
{
|
{
|
||||||
|
$transports = array('omb', 'sms', 'public', 'twitter', 'facebook', 'ping');
|
||||||
|
|
||||||
|
if (common_config('xmpp', 'enabled'))
|
||||||
|
{
|
||||||
|
$transports[] = 'jabber';
|
||||||
|
}
|
||||||
|
|
||||||
if (common_config('queue','subsystem') == 'stomp') {
|
if (common_config('queue','subsystem') == 'stomp') {
|
||||||
// use an external message queue system via STOMP
|
common_enqueue_notice_stomp($notice, $transports);
|
||||||
require_once("Stomp.php");
|
|
||||||
$con = new Stomp(common_config('queue','stomp_server'));
|
|
||||||
if (!$con->connect()) {
|
|
||||||
common_log(LOG_ERR, 'Failed to connect to queue server');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$queue_basename = common_config('queue','queue_basename');
|
|
||||||
foreach (array('jabber', 'omb', 'sms', 'public', 'twitter', 'facebook', 'ping') as $transport) {
|
|
||||||
if (!$con->send(
|
|
||||||
'/queue/'.$queue_basename.'-'.$transport, // QUEUE
|
|
||||||
$notice->id, // BODY of the message
|
|
||||||
array ( // HEADERS of the msg
|
|
||||||
'created' => $notice->created
|
|
||||||
))) {
|
|
||||||
common_log(LOG_ERR, 'Error sending to '.$transport.' queue');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
common_log(LOG_DEBUG, 'complete remote queueing notice ID = ' . $notice->id . ' for ' . $transport);
|
|
||||||
}
|
|
||||||
|
|
||||||
//send tags as headers, so they can be used as JMS selectors
|
|
||||||
common_log(LOG_DEBUG, 'searching for tags ' . $notice->id);
|
|
||||||
$tags = array();
|
|
||||||
$tag = new Notice_tag();
|
|
||||||
$tag->notice_id = $notice->id;
|
|
||||||
if ($tag->find()) {
|
|
||||||
while ($tag->fetch()) {
|
|
||||||
common_log(LOG_DEBUG, 'tag found = ' . $tag->tag);
|
|
||||||
array_push($tags,$tag->tag);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$tag->free();
|
|
||||||
|
|
||||||
$con->send('/topic/laconica.'.$notice->profile_id,
|
|
||||||
$notice->content,
|
|
||||||
array(
|
|
||||||
'profile_id' => $notice->profile_id,
|
|
||||||
'created' => $notice->created,
|
|
||||||
'tags' => implode($tags,' - ')
|
|
||||||
)
|
|
||||||
);
|
|
||||||
common_log(LOG_DEBUG, 'sent to personal topic ' . $notice->id);
|
|
||||||
$con->send('/topic/laconica.allusers',
|
|
||||||
$notice->content,
|
|
||||||
array(
|
|
||||||
'profile_id' => $notice->profile_id,
|
|
||||||
'created' => $notice->created,
|
|
||||||
'tags' => implode($tags,' - ')
|
|
||||||
)
|
|
||||||
);
|
|
||||||
common_log(LOG_DEBUG, 'sent to catch-all topic ' . $notice->id);
|
|
||||||
$result = true;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// in any other case, 'internal'
|
common_enqueue_notice_db($notice, $transports);
|
||||||
foreach (array('jabber', 'omb', 'sms', 'public', 'twitter', 'facebook', 'ping') as $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);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
common_log(LOG_DEBUG, 'complete queueing notice ID = ' . $notice->id . ' for ' . $transport);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function common_post_inbox_transports()
|
function common_enqueue_notice_stomp($notice, $transports)
|
||||||
{
|
{
|
||||||
$transports = array('omb', 'sms');
|
// use an external message queue system via STOMP
|
||||||
|
require_once("Stomp.php");
|
||||||
|
|
||||||
if (common_config('xmpp', 'enabled')) {
|
$server = common_config('queue','stomp_server');
|
||||||
$transports = array_merge($transports, array('jabber', 'public'));
|
$username = common_config('queue', 'stomp_username');
|
||||||
|
$password = common_config('queue', 'stomp_password');
|
||||||
|
|
||||||
|
$con = new Stomp($server);
|
||||||
|
|
||||||
|
if (!$con->connect($username, $password)) {
|
||||||
|
common_log(LOG_ERR, 'Failed to connect to queue server');
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $transports;
|
$queue_basename = common_config('queue','queue_basename');
|
||||||
|
|
||||||
|
foreach ($transports as $transport) {
|
||||||
|
$result = $con->send('/queue/'.$queue_basename.'-'.$transport, // QUEUE
|
||||||
|
$notice->id, // BODY of the message
|
||||||
|
array ('created' => $notice->created));
|
||||||
|
if (!$result) {
|
||||||
|
common_log(LOG_ERR, 'Error sending to '.$transport.' queue');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
common_log(LOG_DEBUG, 'complete remote queueing notice ID = ' . $notice->id . ' for ' . $transport);
|
||||||
|
}
|
||||||
|
|
||||||
|
//send tags as headers, so they can be used as JMS selectors
|
||||||
|
common_log(LOG_DEBUG, 'searching for tags ' . $notice->id);
|
||||||
|
$tags = array();
|
||||||
|
$tag = new Notice_tag();
|
||||||
|
$tag->notice_id = $notice->id;
|
||||||
|
if ($tag->find()) {
|
||||||
|
while ($tag->fetch()) {
|
||||||
|
common_log(LOG_DEBUG, 'tag found = ' . $tag->tag);
|
||||||
|
array_push($tags,$tag->tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$tag->free();
|
||||||
|
|
||||||
|
$con->send('/topic/laconica.'.$notice->profile_id,
|
||||||
|
$notice->content,
|
||||||
|
array(
|
||||||
|
'profile_id' => $notice->profile_id,
|
||||||
|
'created' => $notice->created,
|
||||||
|
'tags' => implode($tags,' - ')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
common_log(LOG_DEBUG, 'sent to personal topic ' . $notice->id);
|
||||||
|
$con->send('/topic/laconica.allusers',
|
||||||
|
$notice->content,
|
||||||
|
array(
|
||||||
|
'profile_id' => $notice->profile_id,
|
||||||
|
'created' => $notice->created,
|
||||||
|
'tags' => implode($tags,' - ')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
common_log(LOG_DEBUG, 'sent to catch-all topic ' . $notice->id);
|
||||||
|
$result = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function common_enqueue_notice_db($notice, $transports)
|
||||||
|
{
|
||||||
|
// in any other case, 'internal'
|
||||||
|
foreach ($transports as $transport) {
|
||||||
|
common_enqueue_notice_transport($notice, $transport);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function common_enqueue_notice_transport($notice, $transport)
|
function common_enqueue_notice_transport($notice, $transport)
|
||||||
|
@ -22,7 +22,7 @@ if (!defined('LACONICA')) { exit(1); }
|
|||||||
require_once(INSTALLDIR.'/lib/queuehandler.php');
|
require_once(INSTALLDIR.'/lib/queuehandler.php');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Common superclass for all XMPP-using queue handlers. They all need to
|
* Common superclass for all XMPP-using queue handlers. They all need to
|
||||||
* service their message queues on idle, and forward any incoming messages
|
* service their message queues on idle, and forward any incoming messages
|
||||||
* to the XMPP listener connection. So, we abstract out common code to a
|
* to the XMPP listener connection. So, we abstract out common code to a
|
||||||
* superclass.
|
* superclass.
|
||||||
@ -30,12 +30,11 @@ require_once(INSTALLDIR.'/lib/queuehandler.php');
|
|||||||
|
|
||||||
class XmppQueueHandler extends QueueHandler
|
class XmppQueueHandler extends QueueHandler
|
||||||
{
|
{
|
||||||
|
|
||||||
function start()
|
function start()
|
||||||
{
|
{
|
||||||
# Low priority; we don't want to receive messages
|
# Low priority; we don't want to receive messages
|
||||||
$this->log(LOG_INFO, "INITIALIZE");
|
$this->log(LOG_INFO, "INITIALIZE");
|
||||||
$this->conn = jabber_connect($this->_id);
|
$this->conn = jabber_connect($this->_id.$this->transport());
|
||||||
if ($this->conn) {
|
if ($this->conn) {
|
||||||
$this->conn->addEventHandler('message', 'forward_message', $this);
|
$this->conn->addEventHandler('message', 'forward_message', $this);
|
||||||
$this->conn->addEventHandler('reconnect', 'handle_reconnect', $this);
|
$this->conn->addEventHandler('reconnect', 'handle_reconnect', $this);
|
||||||
@ -44,7 +43,7 @@ class XmppQueueHandler extends QueueHandler
|
|||||||
}
|
}
|
||||||
return !is_null($this->conn);
|
return !is_null($this->conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handle_reconnect(&$pl)
|
function handle_reconnect(&$pl)
|
||||||
{
|
{
|
||||||
$this->conn->processUntil('session_start');
|
$this->conn->processUntil('session_start');
|
||||||
@ -63,7 +62,7 @@ class XmppQueueHandler extends QueueHandler
|
|||||||
die($e->getMessage());
|
die($e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function forward_message(&$pl)
|
function forward_message(&$pl)
|
||||||
{
|
{
|
||||||
if ($pl['type'] != 'chat') {
|
if ($pl['type'] != 'chat') {
|
||||||
|
40
scripts/allsites.php
Executable file
40
scripts/allsites.php
Executable file
@ -0,0 +1,40 @@
|
|||||||
|
#!/usr/bin/env php
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Laconica - a distributed open-source microblogging tool
|
||||||
|
* Copyright (C) 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
|
||||||
|
|
||||||
|
define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
|
||||||
|
|
||||||
|
$helptext = <<<ENDOFHELP
|
||||||
|
allsites.php - list all sites configured for multi-site use
|
||||||
|
|
||||||
|
returns the nickname of each site configured for multi-site use
|
||||||
|
|
||||||
|
ENDOFHELP;
|
||||||
|
|
||||||
|
require_once INSTALLDIR.'/scripts/commandline.inc';
|
||||||
|
|
||||||
|
$sn = new Status_network();
|
||||||
|
|
||||||
|
if ($sn->find()) {
|
||||||
|
while ($sn->fetch()) {
|
||||||
|
print "$sn->nickname\n";
|
||||||
|
}
|
||||||
|
}
|
21
scripts/delete_status_network.sh
Executable file
21
scripts/delete_status_network.sh
Executable file
@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
source /etc/laconica/setup.cfg
|
||||||
|
|
||||||
|
export nickname=$1
|
||||||
|
|
||||||
|
export database=$nickname$DBBASE
|
||||||
|
|
||||||
|
# Create the db
|
||||||
|
|
||||||
|
mysqladmin -h $DBHOST -u $ADMIN --password=$ADMINPASS -f drop $database
|
||||||
|
|
||||||
|
mysql -h $DBHOST -u $ADMIN --password=$ADMINPASS $SITEDB << ENDOFCOMMANDS
|
||||||
|
|
||||||
|
delete from status_network where nickname = '$nickname';
|
||||||
|
|
||||||
|
ENDOFCOMMANDS
|
||||||
|
|
||||||
|
for top in $AVATARBASE $FILEBASE $BACKGROUNDBASE; do
|
||||||
|
rm -Rf $top/$nickname
|
||||||
|
done
|
@ -38,9 +38,6 @@ if(common_config('xmpp','enabled')) {
|
|||||||
echo "xmppdaemon.php jabberqueuehandler.php publicqueuehandler.php ";
|
echo "xmppdaemon.php jabberqueuehandler.php publicqueuehandler.php ";
|
||||||
echo "xmppconfirmhandler.php ";
|
echo "xmppconfirmhandler.php ";
|
||||||
}
|
}
|
||||||
if(common_config('memcached','enabled')) {
|
|
||||||
echo "memcachedqueuehandler.php ";
|
|
||||||
}
|
|
||||||
if(common_config('twitterbridge','enabled')) {
|
if(common_config('twitterbridge','enabled')) {
|
||||||
echo "twitterstatusfetcher.php ";
|
echo "twitterstatusfetcher.php ";
|
||||||
}
|
}
|
||||||
|
@ -20,13 +20,13 @@
|
|||||||
|
|
||||||
define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
|
define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
|
||||||
|
|
||||||
$shortoptions = 'r::';
|
$shortoptions = 'i::';
|
||||||
$longoptions = array('resource::');
|
$longoptions = array('id::');
|
||||||
|
|
||||||
$helptext = <<<END_OF_JABBER_HELP
|
$helptext = <<<END_OF_JABBER_HELP
|
||||||
Daemon script for pushing new notices to Jabber users.
|
Daemon script for pushing new notices to Jabber users.
|
||||||
|
|
||||||
-r --resource Jabber Resource ID (default to config)
|
-i --id Identity (default none)
|
||||||
|
|
||||||
END_OF_JABBER_HELP;
|
END_OF_JABBER_HELP;
|
||||||
|
|
||||||
@ -63,16 +63,16 @@ if (common_config('xmpp','enabled')==false) {
|
|||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (have_option('r')) {
|
if (have_option('i')) {
|
||||||
$resource = get_option_value('r');
|
$id = get_option_value('i');
|
||||||
} else if (have_option('--resource')) {
|
} else if (have_option('--id')) {
|
||||||
$resource = get_option_value('--resource');
|
$id = get_option_value('--id');
|
||||||
} else if (count($args) > 0) {
|
} else if (count($args) > 0) {
|
||||||
$resource = $args[0];
|
$id = $args[0];
|
||||||
} else {
|
} else {
|
||||||
$resource = null;
|
$id = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$handler = new JabberQueueHandler($resource);
|
$handler = new JabberQueueHandler($id);
|
||||||
|
|
||||||
$handler->runOnce();
|
$handler->runOnce();
|
||||||
|
@ -20,13 +20,13 @@
|
|||||||
|
|
||||||
define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
|
define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
|
||||||
|
|
||||||
$shortoptions = 'r::';
|
$shortoptions = 'i::';
|
||||||
$longoptions = array('resource::');
|
$longoptions = array('id::');
|
||||||
|
|
||||||
$helptext = <<<END_OF_PUBLIC_HELP
|
$helptext = <<<END_OF_PUBLIC_HELP
|
||||||
Daemon script for pushing new notices to public XMPP subscribers.
|
Daemon script for pushing new notices to public XMPP subscribers.
|
||||||
|
|
||||||
-r --resource Jabber Resource ID
|
-i --id Identity (default none)
|
||||||
|
|
||||||
END_OF_PUBLIC_HELP;
|
END_OF_PUBLIC_HELP;
|
||||||
|
|
||||||
@ -61,16 +61,16 @@ if (common_config('xmpp','enabled')==false) {
|
|||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (have_option('r')) {
|
if (have_option('i')) {
|
||||||
$resource = get_option_value('r');
|
$id = get_option_value('i');
|
||||||
} else if (have_option('--resource')) {
|
} else if (have_option('--id')) {
|
||||||
$resource = get_option_value('--resource');
|
$id = get_option_value('--id');
|
||||||
} else if (count($args) > 0) {
|
} else if (count($args) > 0) {
|
||||||
$resource = $args[0];
|
$id = $args[0];
|
||||||
} else {
|
} else {
|
||||||
$resource = null;
|
$id = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$handler = new PublicQueueHandler($resource);
|
$handler = new PublicQueueHandler($id);
|
||||||
|
|
||||||
$handler->runOnce();
|
$handler->runOnce();
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
# CONFIGURATION FILE for setup_status_network.sh
|
# CONFIGURATION FILE for setup_status_network.sh
|
||||||
|
|
||||||
# Base database name; full name will include nickname
|
export DBHOST=localhost
|
||||||
|
export DBHOSTNAME=masterdb.example.net
|
||||||
export DBHOST=masterdb.example.net
|
|
||||||
export DBBASE=_example_net
|
export DBBASE=_example_net
|
||||||
export USERBASE=_example_net
|
export USERBASE=_example_net
|
||||||
export ADMIN=root
|
export ADMIN=root
|
||||||
export ADMINPASS=yourpassword
|
export ADMINPASS=yourpassword
|
||||||
export SITEDB=example_net_site
|
export SITEDB=example_net_site
|
||||||
export AVATARBASE=/var/www/avatar.example.net
|
export AVATARBASE=/var/www/avatar.example.net
|
||||||
|
export BACKGROUNDBASE=/var/www/background.example.net
|
||||||
|
export FILEBASE=/var/www/file.example.net
|
||||||
export PWDGEN="pwgen 20"
|
export PWDGEN="pwgen 20"
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
source ./setup.cfg
|
source /etc/laconica/setup.cfg
|
||||||
|
|
||||||
export nickname=$1
|
export nickname=$1
|
||||||
export sitename=$2
|
export sitename=$2
|
||||||
@ -22,9 +22,11 @@ mysql -h $DBHOST -u $ADMIN --password=$ADMINPASS $SITEDB << ENDOFCOMMANDS
|
|||||||
GRANT INSERT,SELECT,UPDATE,DELETE ON $database.* TO '$username'@'localhost' IDENTIFIED BY '$password';
|
GRANT INSERT,SELECT,UPDATE,DELETE ON $database.* TO '$username'@'localhost' IDENTIFIED BY '$password';
|
||||||
GRANT INSERT,SELECT,UPDATE,DELETE ON $database.* TO '$username'@'%' IDENTIFIED BY '$password';
|
GRANT INSERT,SELECT,UPDATE,DELETE ON $database.* TO '$username'@'%' IDENTIFIED BY '$password';
|
||||||
INSERT INTO status_network (nickname, dbhost, dbuser, dbpass, dbname, sitename, created)
|
INSERT INTO status_network (nickname, dbhost, dbuser, dbpass, dbname, sitename, created)
|
||||||
VALUES ('$nickname', '$DBHOST', '$username', '$password', '$database', '$sitename', now());
|
VALUES ('$nickname', '$DBHOSTNAME', '$username', '$password', '$database', '$sitename', now());
|
||||||
|
|
||||||
ENDOFCOMMANDS
|
ENDOFCOMMANDS
|
||||||
|
|
||||||
mkdir $AVATARBASE/$nickname
|
for top in $AVATARBASE $FILEBASE $BACKGROUNDBASE; do
|
||||||
chmod a+w $AVATARBASE/$nickname
|
mkdir $top/$nickname
|
||||||
|
chmod a+w $top/$nickname
|
||||||
|
done
|
||||||
|
@ -20,12 +20,27 @@
|
|||||||
# This program tries to start the daemons for Laconica.
|
# This program tries to start the daemons for Laconica.
|
||||||
# Note that the 'maildaemon' needs to run as a mail filter.
|
# Note that the 'maildaemon' needs to run as a mail filter.
|
||||||
|
|
||||||
|
ARGSG=
|
||||||
|
ARGSD=
|
||||||
|
|
||||||
|
if [ $# -gt 0 ]; then
|
||||||
|
ARGSG="$ARGSG -s$1"
|
||||||
|
ID=`echo $1 | sed s/\\\\./_/g`
|
||||||
|
ARGSD="$ARGSD -s$1 -i$ID"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $# -gt 1 ]; then
|
||||||
|
ARGSD="$ARGSD -p$2"
|
||||||
|
ARGSG="$ARGSG -p$2"
|
||||||
|
fi
|
||||||
|
|
||||||
DIR=`dirname $0`
|
DIR=`dirname $0`
|
||||||
DAEMONS=`php $DIR/getvaliddaemons.php`
|
DAEMONS=`php $DIR/getvaliddaemons.php $ARGSG`
|
||||||
|
|
||||||
for f in $DAEMONS; do
|
for f in $DAEMONS; do
|
||||||
|
|
||||||
echo -n "Starting $f...";
|
printf "Starting $f...";
|
||||||
php $DIR/$f
|
php $DIR/$f $ARGSD
|
||||||
echo "DONE."
|
printf "DONE.\n"
|
||||||
|
|
||||||
done
|
done
|
||||||
|
@ -20,13 +20,13 @@
|
|||||||
|
|
||||||
define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
|
define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
|
||||||
|
|
||||||
$shortoptions = 'r::';
|
$shortoptions = 'i::';
|
||||||
$longoptions = array('resource::');
|
$longoptions = array('id::');
|
||||||
|
|
||||||
$helptext = <<<END_OF_JABBER_HELP
|
$helptext = <<<END_OF_JABBER_HELP
|
||||||
Daemon script for pushing new confirmations to Jabber users.
|
Daemon script for pushing new confirmations to Jabber users.
|
||||||
|
|
||||||
-r --resource Jabber Resource ID (default to config)
|
-i --id Identity (default none)
|
||||||
|
|
||||||
END_OF_JABBER_HELP;
|
END_OF_JABBER_HELP;
|
||||||
|
|
||||||
@ -147,17 +147,17 @@ if (common_config('xmpp','enabled')==false) {
|
|||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (have_option('r')) {
|
if (have_option('i')) {
|
||||||
$resource = get_option_value('r');
|
$id = get_option_value('i');
|
||||||
} else if (have_option('--resource')) {
|
} else if (have_option('--id')) {
|
||||||
$resource = get_option_value('--resource');
|
$id = get_option_value('--id');
|
||||||
} else if (count($args) > 0) {
|
} else if (count($args) > 0) {
|
||||||
$resource = $args[0];
|
$id = $args[0];
|
||||||
} else {
|
} else {
|
||||||
$resource = null;
|
$id = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$handler = new XmppConfirmHandler($resource);
|
$handler = new XmppConfirmHandler($id);
|
||||||
|
|
||||||
$handler->runOnce();
|
$handler->runOnce();
|
||||||
|
|
||||||
|
@ -20,13 +20,13 @@
|
|||||||
|
|
||||||
define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
|
define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
|
||||||
|
|
||||||
$shortoptions = 'r::';
|
$shortoptions = 'i::';
|
||||||
$longoptions = array('resource::');
|
$longoptions = array('id::');
|
||||||
|
|
||||||
$helptext = <<<END_OF_XMPP_HELP
|
$helptext = <<<END_OF_XMPP_HELP
|
||||||
Daemon script for receiving new notices from Jabber users.
|
Daemon script for receiving new notices from Jabber users.
|
||||||
|
|
||||||
-r --resource Jabber Resource ID (default to config)
|
-i --id Identity (default none)
|
||||||
|
|
||||||
END_OF_XMPP_HELP;
|
END_OF_XMPP_HELP;
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ class XMPPDaemon extends Daemon
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($resource) {
|
if ($resource) {
|
||||||
$this->resource = $resource;
|
$this->resource = $resource . 'daemon';
|
||||||
} else {
|
} else {
|
||||||
$this->resource = common_config('xmpp', 'resource') . 'daemon';
|
$this->resource = common_config('xmpp', 'resource') . 'daemon';
|
||||||
}
|
}
|
||||||
@ -323,16 +323,16 @@ if (common_config('xmpp','enabled')==false) {
|
|||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (have_option('r')) {
|
if (have_option('i')) {
|
||||||
$resource = get_option_value('r');
|
$id = get_option_value('i');
|
||||||
} else if (have_option('--resource')) {
|
} else if (have_option('--id')) {
|
||||||
$resource = get_option_value('--resource');
|
$id = get_option_value('--id');
|
||||||
} else if (count($args) > 0) {
|
} else if (count($args) > 0) {
|
||||||
$resource = $args[0];
|
$id = $args[0];
|
||||||
} else {
|
} else {
|
||||||
$resource = null;
|
$id = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$daemon = new XMPPDaemon($resource);
|
$daemon = new XMPPDaemon($id);
|
||||||
|
|
||||||
$daemon->runOnce();
|
$daemon->runOnce();
|
||||||
|
@ -510,13 +510,26 @@ margin-bottom:7px;
|
|||||||
margin-left:18px;
|
margin-left:18px;
|
||||||
float:left;
|
float:left;
|
||||||
}
|
}
|
||||||
#form_notice .error {
|
#form_notice .error,
|
||||||
|
#form_notice .success {
|
||||||
float:left;
|
float:left;
|
||||||
clear:both;
|
clear:both;
|
||||||
width:96.9%;
|
width:81.5%;
|
||||||
margin-bottom:0;
|
margin-bottom:0;
|
||||||
line-height:1.618;
|
line-height:1.618;
|
||||||
}
|
}
|
||||||
|
#form_notice #notice_data-attach_selected code {
|
||||||
|
float:left;
|
||||||
|
width:90%;
|
||||||
|
display:block;
|
||||||
|
font-size:1.1em;
|
||||||
|
line-height:1.8;
|
||||||
|
overflow:auto;
|
||||||
|
}
|
||||||
|
#form_notice #notice_data-attach_selected button {
|
||||||
|
float:right;
|
||||||
|
font-size:0.8em;
|
||||||
|
}
|
||||||
|
|
||||||
/* entity_profile */
|
/* entity_profile */
|
||||||
.entity_profile {
|
.entity_profile {
|
||||||
@ -548,7 +561,8 @@ margin-bottom:18px;
|
|||||||
.entity_profile .entity_location,
|
.entity_profile .entity_location,
|
||||||
.entity_profile .entity_url,
|
.entity_profile .entity_url,
|
||||||
.entity_profile .entity_note,
|
.entity_profile .entity_note,
|
||||||
.entity_profile .entity_tags {
|
.entity_profile .entity_tags,
|
||||||
|
.entity_profile .entity_aliases {
|
||||||
margin-left:113px;
|
margin-left:113px;
|
||||||
margin-bottom:4px;
|
margin-bottom:4px;
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,12 @@ display:block;
|
|||||||
width:17%;
|
width:17%;
|
||||||
max-width:17%;
|
max-width:17%;
|
||||||
}
|
}
|
||||||
|
#form_notice #notice_data-attach_selected {
|
||||||
|
width:78.5%;
|
||||||
|
}
|
||||||
|
#form_notice #notice_data-attach_selected button {
|
||||||
|
padding:0 4px;
|
||||||
|
}
|
||||||
#anon_notice {
|
#anon_notice {
|
||||||
max-width:39%;
|
max-width:39%;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
body,
|
body,
|
||||||
a:active {
|
a:active {
|
||||||
background-color:#C3D6DF;
|
background-color:#CEE1E9;
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;
|
font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;
|
||||||
@ -29,7 +29,7 @@ input, textarea, select,
|
|||||||
border-color:#AAAAAA;
|
border-color:#AAAAAA;
|
||||||
}
|
}
|
||||||
#filter_tags ul li {
|
#filter_tags ul li {
|
||||||
border-color:#C3D6DF;
|
border-color:#DDDDDD;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form_settings input.form_action-primary {
|
.form_settings input.form_action-primary {
|
||||||
@ -40,12 +40,12 @@ input.submit,
|
|||||||
#form_notice.warning #notice_text-count,
|
#form_notice.warning #notice_text-count,
|
||||||
.form_settings .form_note,
|
.form_settings .form_note,
|
||||||
.entity_remote_subscribe {
|
.entity_remote_subscribe {
|
||||||
background-color:#A9BF4F;
|
background-color:#9BB43E;
|
||||||
}
|
}
|
||||||
|
|
||||||
input:focus, textarea:focus, select:focus,
|
input:focus, textarea:focus, select:focus,
|
||||||
#form_notice.warning #notice_data-text {
|
#form_notice.warning #notice_data-text {
|
||||||
border-color:#A9BF4F;
|
border-color:#9BB43E;
|
||||||
box-shadow:3px 3px 3px rgba(194, 194, 194, 0.3);
|
box-shadow:3px 3px 3px rgba(194, 194, 194, 0.3);
|
||||||
-moz-box-shadow:3px 3px 3px rgba(194, 194, 194, 0.3);
|
-moz-box-shadow:3px 3px 3px rgba(194, 194, 194, 0.3);
|
||||||
-webkit-box-shadow:3px 3px 3px rgba(194, 194, 194, 0.3);
|
-webkit-box-shadow:3px 3px 3px rgba(194, 194, 194, 0.3);
|
||||||
@ -71,14 +71,14 @@ color:#002E6E;
|
|||||||
|
|
||||||
.notice,
|
.notice,
|
||||||
.profile {
|
.profile {
|
||||||
border-top-color:#D1D9E4;
|
border-top-color:#C8D1D5;
|
||||||
}
|
}
|
||||||
.section .profile {
|
.section .profile {
|
||||||
border-top-color:#C3D6DF;
|
border-top-color:#87B4C8;
|
||||||
}
|
}
|
||||||
|
|
||||||
#aside_primary {
|
#aside_primary {
|
||||||
background-color:#CEE1E9;
|
background-color:#C8D1D5;
|
||||||
}
|
}
|
||||||
|
|
||||||
#notice_text-count {
|
#notice_text-count {
|
||||||
@ -136,13 +136,13 @@ background-color:#EFF3DC;
|
|||||||
}
|
}
|
||||||
|
|
||||||
#anon_notice {
|
#anon_notice {
|
||||||
background-color:#C3D6DF;
|
background-color:#87B4C8;
|
||||||
color:#FFFFFF;
|
color:#FFFFFF;
|
||||||
border-color:#FFFFFF;
|
border-color:#FFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
#showstream #anon_notice {
|
#showstream #anon_notice {
|
||||||
background-color:#A9BF4F;
|
background-color:#9BB43E;
|
||||||
}
|
}
|
||||||
|
|
||||||
#export_data li a {
|
#export_data li a {
|
||||||
@ -176,13 +176,13 @@ background-color:transparent;
|
|||||||
.form_group_leave input.submit
|
.form_group_leave input.submit
|
||||||
.form_user_subscribe input.submit,
|
.form_user_subscribe input.submit,
|
||||||
.form_user_unsubscribe input.submit {
|
.form_user_unsubscribe input.submit {
|
||||||
background-color:#A9BF4F;
|
background-color:#9BB43E;
|
||||||
color:#FFFFFF;
|
color:#FFFFFF;
|
||||||
}
|
}
|
||||||
.form_user_unsubscribe input.submit,
|
.form_user_unsubscribe input.submit,
|
||||||
.form_group_leave input.submit,
|
.form_group_leave input.submit,
|
||||||
.form_user_authorization input.reject {
|
.form_user_authorization input.reject {
|
||||||
background-color:#C3D6DF;
|
background-color:#87B4C8;
|
||||||
}
|
}
|
||||||
|
|
||||||
.entity_edit a {
|
.entity_edit a {
|
||||||
@ -245,7 +245,7 @@ div.notice-options input {
|
|||||||
font-family:sans-serif;
|
font-family:sans-serif;
|
||||||
}
|
}
|
||||||
#content .notices li:hover {
|
#content .notices li:hover {
|
||||||
background-color:#FCFCFC;
|
background-color:rgba(240, 240, 240, 0.2);
|
||||||
}
|
}
|
||||||
#conversation .notices li:hover {
|
#conversation .notices li:hover {
|
||||||
background-color:transparent;
|
background-color:transparent;
|
||||||
@ -272,7 +272,7 @@ background:transparent url(../../base/images/icons/twotone/green/news.gif) no-re
|
|||||||
.pagination .nav_prev a,
|
.pagination .nav_prev a,
|
||||||
.pagination .nav_next a {
|
.pagination .nav_next a {
|
||||||
background-repeat:no-repeat;
|
background-repeat:no-repeat;
|
||||||
border-color:#D1D9E4;
|
border-color:#C8D1D5;
|
||||||
}
|
}
|
||||||
.pagination .nav_prev a {
|
.pagination .nav_prev a {
|
||||||
background-image:url(../../base/images/icons/twotone/green/arrow-left.gif);
|
background-image:url(../../base/images/icons/twotone/green/arrow-left.gif);
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
/* IE specific styles */
|
/* IE specific styles */
|
||||||
|
|
||||||
.notice-options input.submit {
|
.notice-options input.submit {
|
||||||
color:#fff;
|
color:#FFFFFF;
|
||||||
}
|
}
|
||||||
#site_nav_local_views a {
|
#site_nav_local_views a {
|
||||||
background-color:#ACCCDA;
|
background-color:#C8D1D5;
|
||||||
}
|
}
|
||||||
#form_notice .form_note + label {
|
#form_notice .form_note + label {
|
||||||
background:transparent url(../../base/images/icons/twotone/green/clip-01.gif) no-repeat 0 45%;
|
background:transparent url(../../base/images/icons/twotone/green/clip-01.gif) no-repeat 0 45%;
|
||||||
}
|
}
|
||||||
#form_notice #notice_data-attach {
|
#form_notice #notice_data-attach {
|
||||||
filter: alpha(opacity=0);
|
filter: alpha(opacity=0);
|
||||||
}
|
}
|
||||||
|
@ -245,7 +245,7 @@ div.notice-options input {
|
|||||||
font-family:sans-serif;
|
font-family:sans-serif;
|
||||||
}
|
}
|
||||||
#content .notices li:hover {
|
#content .notices li:hover {
|
||||||
background-color:#FCFCFC;
|
background-color:rgba(240, 240, 240, 0.2);
|
||||||
}
|
}
|
||||||
#conversation .notices li:hover {
|
#conversation .notices li:hover {
|
||||||
background-color:transparent;
|
background-color:transparent;
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
/* IE specific styles */
|
/* IE specific styles */
|
||||||
|
|
||||||
.notice-options input.submit {
|
.notice-options input.submit {
|
||||||
color:#fff;
|
color:#FFFFFF;
|
||||||
}
|
}
|
||||||
#site_nav_local_views a {
|
#site_nav_local_views a {
|
||||||
background-color:#D0DFE7;
|
background-color:#D9DADB;
|
||||||
}
|
}
|
||||||
#form_notice .form_note + label {
|
#form_notice .form_note + label {
|
||||||
background:transparent url(../../base/images/icons/twotone/green/clip-01.gif) no-repeat 0 45%;
|
background:transparent url(../../base/images/icons/twotone/green/clip-01.gif) no-repeat 0 45%;
|
||||||
}
|
}
|
||||||
#form_notice #notice_data-attach {
|
#form_notice #notice_data-attach {
|
||||||
filter: alpha(opacity=0);
|
filter: alpha(opacity=0);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user