Merge branch '0.7.x' of git://gitorious.org/laconica/dev into 0.7.x

This commit is contained in:
Tobias Diekershoff 2009-03-26 06:56:52 +01:00
commit d1bf8b2143
32 changed files with 398 additions and 239 deletions

View File

@ -1,9 +1,4 @@
<?php
// define('GROUPS_PER_PAGE', 20);
/**
* Group search action class.
*
@ -90,15 +85,15 @@ class GroupSearchResults extends GroupList
{
var $terms = null;
var $pattern = null;
function __construct($user_group, $terms, $action)
{
parent::__construct($user_group, $terms, $action);
$this->terms = array_map('preg_quote',
$this->terms = array_map('preg_quote',
array_map('htmlspecialchars', $terms));
$this->pattern = '/('.implode('|',$terms).')/i';
}
function highlight($text)
{
return preg_replace($this->pattern, '<strong>\\1</strong>', htmlspecialchars($text));

View File

@ -103,7 +103,7 @@ class NoticesearchAction extends SearchAction
function showResults($q, $page)
{
$notice = new Notice();
$q = strtolower($q);
$search_engine = $notice->getSearchEngine('identica_notices');
$search_engine->set_sort_mode('chron');
// Ask for an extra to see if there's more.
@ -122,9 +122,10 @@ class NoticesearchAction extends SearchAction
$cnt = $nl->show();
$this->pagination($this->page > 1, $cnt > NOTICES_PER_PAGE,
$this->page, 'noticesearch', array('q' => $q));
$this->pagination($page > 1, $cnt > NOTICES_PER_PAGE,
$page, 'noticesearch', array('q' => $q));
}
function isReadOnly()
{
return true;

View File

@ -62,9 +62,6 @@ class NoticesearchrssAction extends Rss10Action
$notice = new Notice();
# lcase it for comparison
$q = strtolower($q);
$search_engine = $notice->getSearchEngine('identica_notices');
$search_engine->set_sort_mode('chron');

View File

@ -63,13 +63,13 @@ class PeoplesearchAction extends SearchAction
$profile = new Profile();
# lcase it for comparison
$q = strtolower($q);
// lcase it for comparison
// $q = strtolower($q);
$search_engine = $profile->getSearchEngine('identica_people');
$search_engine->set_sort_mode('chron');
# Ask for an extra to see if there's more.
// Ask for an extra to see if there's more.
$search_engine->limit((($page-1)*PROFILES_PER_PAGE), PROFILES_PER_PAGE + 1);
if (false === $search_engine->query($q)) {
$cnt = 0;

View File

@ -207,9 +207,14 @@ class PublicAction extends Action
function showAnonymousMessage()
{
$m = _('This is %%site.name%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
'based on the Free Software [Laconica](http://laconi.ca/) tool. ' .
'[Join now](%%action.register%%) to share notices about yourself with friends, family, and colleagues! ([Read more](%%doc.help%%))');
if (! (common_config('site','closed') || common_config('site','inviteonly'))) {
$m = _('This is %%site.name%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
'based on the Free Software [Laconica](http://laconi.ca/) tool. ' .
'[Join now](%%action.register%%) to share notices about yourself with friends, family, and colleagues! ([Read more](%%doc.help%%))');
} else {
$m = _('This is %%site.name%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
'based on the Free Software [Laconica](http://laconi.ca/) tool.');
}
$this->elementStart('div', array('id' => 'anon_notice'));
$this->raw(common_markup_to_html($m));
$this->elementEnd('div');

View File

@ -181,13 +181,21 @@ class RecoverpasswordAction extends Action
function showRecoverForm()
{
$this->elementStart('form', array('method' => 'post',
'id' => 'recoverpassword',
'id' => 'form_password_recover',
'class' => 'form_settings',
'action' => common_local_url('recoverpassword')));
$this->elementStart('fieldset');
$this->element('legend', null, _('Password recover'));
$this->elementStart('ul', 'form_data');
$this->elementStart('li');
$this->input('nicknameoremail', _('Nickname or email'),
$this->trimmed('nicknameoremail'),
_('Your nickname on this server, ' .
'or your registered email address.'));
$this->elementEnd('li');
$this->elementEnd('ul');
$this->submit('recover', _('Recover'));
$this->elementEnd('fieldset');
$this->elementEnd('form');
}
@ -213,14 +221,24 @@ class RecoverpasswordAction extends Action
function showResetForm()
{
$this->elementStart('form', array('method' => 'post',
'id' => 'recoverpassword',
'id' => 'form_password_change',
'class' => 'form_settings',
'action' => common_local_url('recoverpassword')));
$this->elementStart('fieldset');
$this->element('legend', null, _('Password change'));
$this->hidden('token', common_session_token());
$this->elementStart('ul', 'form_data');
$this->elementStart('li');
$this->password('newpassword', _('New password'),
_('6 or more characters, and don\'t forget it!'));
$this->elementEnd('li');
$this->elementStart('li');
$this->password('confirm', _('Confirm'),
_('Same as password above'));
$this->elementEnd('li');
$this->elementEnd('ul');
$this->submit('reset', _('Reset'));
$this->elementEnd('fieldset');
$this->elementEnd('form');
}

View File

@ -390,11 +390,18 @@ class ShowgroupAction extends Action
function showAnonymousMessage()
{
$m = sprintf(_('**%s** is a user group on %%%%site.name%%%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
'based on the Free Software [Laconica](http://laconi.ca/) tool. Its members share ' .
'short messages about their life and interests. '.
'[Join now](%%%%action.register%%%%) to become part of this group and many more! ([Read more](%%%%doc.help%%%%))'),
if (!(common_config('site','closed') || common_config('site','inviteonly'))) {
$m = sprintf(_('**%s** is a user group on %%%%site.name%%%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
'based on the Free Software [Laconica](http://laconi.ca/) tool. Its members share ' .
'short messages about their life and interests. '.
'[Join now](%%%%action.register%%%%) to become part of this group and many more! ([Read more](%%%%doc.help%%%%))'),
$this->group->nickname);
} else {
$m = sprintf(_('**%s** is a user group on %%%%site.name%%%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
'based on the Free Software [Laconica](http://laconi.ca/) tool. Its members share ' .
'short messages about their life and interests. '),
$this->group->nickname);
}
$this->elementStart('div', array('id' => 'anon_notice'));
$this->raw(common_markup_to_html($m));
$this->elementEnd('div');

View File

@ -177,10 +177,17 @@ class ShownoticeAction extends Action
{
parent::handle($args);
$this->showPage();
if ($this->notice->is_local == 0) {
if (!empty($this->notice->url)) {
common_redirect($this->notice->url, 301);
} else if (!empty($this->notice->uri) && preg_match('/^https?:/', $this->notice->uri)) {
common_redirect($this->notice->uri, 301);
}
} else {
$this->showPage();
}
}
/**
* Don't show local navigation
*
@ -191,7 +198,6 @@ class ShownoticeAction extends Action
{
}
/**
* Fill the content area of the page
*
@ -208,8 +214,6 @@ class ShownoticeAction extends Action
$this->elementEnd('ul');
}
/**
* Don't show page notice
*
@ -220,7 +224,6 @@ class ShownoticeAction extends Action
{
}
/**
* Don't show aside
*
@ -230,7 +233,6 @@ class ShownoticeAction extends Action
function showAside() {
}
/**
* Extra <head> content
*

View File

@ -539,10 +539,16 @@ class ShowstreamAction extends Action
function showAnonymousMessage()
{
$m = sprintf(_('**%s** has an account on %%%%site.name%%%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
'based on the Free Software [Laconica](http://laconi.ca/) tool. ' .
'[Join now](%%%%action.register%%%%) to follow **%s**\'s notices and many more! ([Read more](%%%%doc.help%%%%))'),
$this->user->nickname, $this->user->nickname);
if (!(common_config('site','closed') || common_config('site','inviteonly'))) {
$m = sprintf(_('**%s** has an account on %%%%site.name%%%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
'based on the Free Software [Laconica](http://laconi.ca/) tool. ' .
'[Join now](%%%%action.register%%%%) to follow **%s**\'s notices and many more! ([Read more](%%%%doc.help%%%%))'),
$this->user->nickname, $this->user->nickname);
} else {
$m = sprintf(_('**%s** has an account on %%%%site.name%%%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
'based on the Free Software [Laconica](http://laconi.ca/) tool. '),
$this->user->nickname, $this->user->nickname);
}
$this->elementStart('div', array('id' => 'anon_notice'));
$this->raw(common_markup_to_html($m));
$this->elementEnd('div');

BIN
apple-touch-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@ -799,4 +799,98 @@ class Notice extends Memcached_DataObject
}
}
}
function asAtomEntry($namespace=false, $source=false)
{
$profile = $this->getProfile();
$xs = new XMLStringer(true);
if ($namespace) {
$attrs = array('xmlns' => 'http://www.w3.org/2005/Atom',
'xmlns:thr' => 'http://purl.org/syndication/thread/1.0');
} else {
$attrs = array();
}
$xs->elementStart('entry', $attrs);
if ($source) {
$xs->elementStart('source');
$xs->element('title', null, $profile->nickname . " - " . common_config('site', 'name'));
$xs->element('link', array('href' => $profile->profileurl));
$user = User::staticGet('id', $profile->id);
if (!empty($user)) {
$atom_feed = common_local_url('api',
array('apiaction' => 'statuses',
'method' => 'user_timeline',
'argument' => $profile->nickname.'.atom'));
$xs->element('link', array('rel' => 'self',
'type' => 'application/atom+xml',
'href' => $profile->profileurl));
$xs->element('link', array('rel' => 'license',
'href' => common_config('license', 'url')));
}
$xs->element('icon', null, $profile->avatarUrl(AVATAR_PROFILE_SIZE));
}
$xs->elementStart('author');
$xs->element('name', null, $profile->nickname);
$xs->element('uri', null, $profile->profileurl);
$xs->elementEnd('author');
if ($source) {
$xs->elementEnd('source');
}
$xs->element('title', null, $this->content);
$xs->element('summary', null, $this->content);
$xs->element('link', array('rel' => 'alternate',
'href' => $this->bestUrl()));
$xs->element('id', null, $this->uri);
$xs->element('published', null, common_date_w3dtf($this->created));
$xs->element('updated', null, common_date_w3dtf($this->modified));
if ($this->reply_to) {
$reply_notice = Notice::staticGet('id', $this->reply_to);
if (!empty($reply_notice)) {
$xs->element('link', array('rel' => 'related',
'href' => $reply_notice->bestUrl()));
$xs->element('thr:in-reply-to',
array('ref' => $reply_notice->uri,
'href' => $reply_notice->bestUrl()));
}
}
$xs->element('content', array('type' => 'html'), $this->rendered);
$tag = new Notice_tag();
$tag->notice_id = $this->id;
if ($tag->find()) {
while ($tag->fetch()) {
$xs->element('category', array('term' => $tag->tag));
}
}
$tag->free();
$xs->elementEnd('entry');
return $xs->getString();
}
function bestUrl()
{
if (!empty($this->url)) {
return $this->url;
} else if (!empty($this->uri) && preg_match('/^https?:/', $this->uri)) {
return $this->uri;
} else {
return common_local_url('shownotice',
array('notice' => $this->id));
}
}
}

View File

@ -19,6 +19,7 @@ VALUES
('identichat','identichat','http://identichat.prosody.im/', now()),
('identitwitch','IdentiTwitch','http://richfish.org/identitwitch/', now()),
('mbpidgin','mbpidgin','http://code.google.com/p/microblog-purple/', now()),
('Mobidentica', 'Mobidentica', 'http://www.substanceofcode.com/software/mobidentica/', now()),
('moconica','Moconica','http://moconica.com/', now()),
('pocketwit','PockeTwit','http://code.google.com/p/pocketwit/', now()),
('posty','Posty','http://spreadingfunkyness.com/posty/', now()),
@ -44,4 +45,4 @@ VALUES
('twitux','Twitux','http://live.gnome.org/DanielMorales/Twitux', now()),
('twitvim','TwitVim','http://vim.sourceforge.net/scripts/script.php?script_id=2204', now()),
('urfastr','urfastr','http://urfastr.net/', now()),
('adium', 'Adium', 'http://www.adiumx.com/', now()));
('adium', 'Adium', 'http://www.adiumx.com/', now());

View File

@ -161,6 +161,7 @@ $(document).ready(function(){
$("#form_notice").addClass("warning");
return false;
}
$("#form_notice").addClass("processing");
$("#notice_action-submit").attr("disabled", "disabled");
$("#notice_action-submit").addClass("disabled");
return true;
@ -179,6 +180,7 @@ $(document).ready(function(){
NoticeHover();
NoticeReply();
}
$("#form_notice").removeClass("processing");
$("#notice_action-submit").removeAttr("disabled");
$("#notice_action-submit").removeClass("disabled");
}

View File

@ -112,6 +112,7 @@ class Action extends HTMLOutputter // lawsuit
// XXX: attributes (profile?)
$this->elementStart('head');
$this->showTitle();
$this->showShortcutIcon();
$this->showStylesheets();
$this->showScripts();
$this->showOpenSearch();
@ -147,6 +148,32 @@ class Action extends HTMLOutputter // lawsuit
return _("Untitled page");
}
/**
* Show themed shortcut icon
*
* @return nothing
*/
function showShortcutIcon()
{
if (is_readable(INSTALLDIR . '/theme/' . common_config('site', 'theme') . '/favicon.ico')) {
$this->element('link', array('rel' => 'shortcut icon',
'href' => theme_path('favicon.ico')));
} else {
$this->element('link', array('rel' => 'shortcut icon',
'href' => common_path('favicon.ico')));
}
if (common_config('site', 'mobile')) {
if (is_readable(INSTALLDIR . '/theme/' . common_config('site', 'theme') . '/apple-touch-icon.png')) {
$this->element('link', array('rel' => 'apple-touch-icon',
'href' => theme_path('apple-touch-icon.png')));
} else {
$this->element('link', array('rel' => 'apple-touch-icon',
'href' => common_path('apple-touch-icon.png')));
}
}
}
/**
* Show stylesheets
*

View File

@ -163,50 +163,25 @@ function jabber_send_notice($to, $notice)
function jabber_format_entry($profile, $notice)
{
// FIXME: notice url might be remote
$entry = $notice->asAtomEntry(true, true);
$noticeurl = common_local_url('shownotice',
array('notice' => $notice->id));
$msg = jabber_format_notice($profile, $notice);
$self_url = common_local_url('userrss', array('nickname' => $profile->nickname));
$entry = "\n<entry xmlns='http://www.w3.org/2005/Atom'>\n";
$entry .= "<source>\n";
$entry .= "<title>" . $profile->nickname . " - " . common_config('site', 'name') . "</title>\n";
$entry .= "<link href='" . htmlspecialchars($profile->profileurl) . "'/>\n";
$entry .= "<link rel='self' type='application/rss+xml' href='" . $self_url . "'/>\n";
$entry .= "<author><name>" . $profile->nickname . "</name></author>\n";
$entry .= "<icon>" . $profile->avatarUrl(AVATAR_PROFILE_SIZE) . "</icon>\n";
$entry .= "</source>\n";
$entry .= "<title>" . htmlspecialchars($msg) . "</title>\n";
$entry .= "<summary>" . htmlspecialchars($msg) . "</summary>\n";
$entry .= "<link rel='alternate' href='" . $noticeurl . "' />\n";
$entry .= "<id>". $notice->uri . "</id>\n";
$entry .= "<published>".common_date_w3dtf($notice->created)."</published>\n";
$entry .= "<updated>".common_date_w3dtf($notice->modified)."</updated>\n";
if ($notice->reply_to) {
$replyurl = common_local_url('shownotice',
array('notice' => $notice->reply_to));
$entry .= "<link rel='related' href='" . $replyurl . "'/>\n";
$xs = new XMLStringer();
$xs->elementStart('html', array('xmlns' => 'http://jabber.org/protocol/xhtml-im'));
$xs->elementStart('body', array('xmlns' => 'http://www.w3.org/1999/xhtml'));
$xs->element('a', array('href' => $profile->profileurl),
$profile->nickname);
$xs->text(": ");
if (!empty($notice->rendered)) {
$xs->raw($notice->rendered);
} else {
$xs->raw(common_render_content($notice->content, $notice));
}
$entry .= "</entry>\n";
$xs->elementEnd('body');
$xs->elementEnd('html');
$html = "\n<html xmlns='http://jabber.org/protocol/xhtml-im'>\n";
$html .= "<body xmlns='http://www.w3.org/1999/xhtml'>\n";
$html .= "<a href='".htmlspecialchars($profile->profileurl)."'>".$profile->nickname."</a>: ";
$html .= ($notice->rendered) ? $notice->rendered : common_render_content($notice->content, $notice);
$html .= "\n</body>\n";
$html .= "\n</html>\n";
$html = $xs->getString();
$address = "<addresses xmlns='http://jabber.org/protocol/address'>\n";
$address .= "<address type='replyto' jid='" . jabber_daemon_address() . "' />\n";
$address .= "</addresses>\n";
// FIXME: include a pubsub event, too.
return $html . $entry . $address;
return $html . ' ' . $entry;
}
/**

View File

@ -115,7 +115,7 @@ function get_all_languages() {
'he' => array('q' => 0.5, 'lang' => 'he_IL', 'name' => 'Hebrew', 'direction' => 'rtl'),
'it' => array('q' => 1, 'lang' => 'it_IT', 'name' => 'Italian', 'direction' => 'ltr'),
'jp' => array('q' => 0.5, 'lang' => 'ja_JP', 'name' => 'Japanese', 'direction' => 'ltr'),
'ko' => array('q' => 0.9, 'lang' => 'ko', 'name' => 'Korean', 'direction' => 'ltr'),
'ko' => array('q' => 0.9, 'lang' => 'ko_KR', 'name' => 'Korean', 'direction' => 'ltr'),
'mk' => array('q' => 0.5, 'lang' => 'mk_MK', 'name' => 'Macedonian', 'direction' => 'ltr'),
'nb' => array('q' => 0.1, 'lang' => 'nb_NO', 'name' => 'Norwegian (Bokmål)', 'direction' => 'ltr'),
'no' => array('q' => 0.1, 'lang' => 'nb_NO', 'name' => 'Norwegian (Bokmål)', 'direction' => 'ltr'),

View File

@ -70,16 +70,16 @@ class LoginGroupNav extends Widget
function show()
{
// action => array('prompt', 'title')
$menu =
array('login' =>
array(_('Login'),
_('Login with a username and password')),
'register' =>
array(_('Register'),
_('Sign up for a new account')),
'openidlogin' =>
array(_('OpenID'),
_('Login or register with OpenID')));
$menu = array();
$menu['login'] = array(_('Login'),
_('Login with a username and password'));
if (!(common_config('site','closed') || common_config('site','inviteonly'))) {
$menu['register'] = array(_('Register'),
_('Sign up for a new account'));
}
$menu['openidlogin'] = array(_('OpenID'),
_('Login or register with OpenID'));
$action_name = $this->action->trimmed('action');
$this->action->elementStart('ul', array('class' => 'nav'));

View File

@ -554,17 +554,19 @@ function mail_notify_fave($other, $user, $notice)
$body = sprintf(_("%1\$s just added your notice from %2\$s".
" as one of their favorites.\n\n" .
"In case you forgot, you can see the text".
" of your notice here:\n\n" .
"The URL of your notice is:\n\n" .
"%3\$s\n\n" .
"You can see the list of %1\$s's favorites here:\n\n" .
"The text of your notice is:\n\n" .
"%4\$s\n\n" .
"You can see the list of %1\$s's favorites here:\n\n" .
"%5\$s\n\n" .
"Faithfully yours,\n" .
"%5\$s\n"),
"%6\$s\n"),
$bestname,
common_exact_date($notice->created),
common_local_url('shownotice',
array('notice' => $notice->id)),
$notice->content,
common_local_url('showfavorites',
array('nickname' => $user->nickname)),
common_config('site', 'name'));

View File

@ -132,20 +132,14 @@ class MessageForm extends Form
$mutual_users->free();
unset($mutual_users);
$this->out->elementStart('ul', 'form_data');
$this->out->elementStart('li', array('id' => 'notice_to'));
$this->out->dropdown('to', _('To'), $mutual, null, false,
($this->to) ? $this->to->id : null);
$this->out->elementEnd('li');
$this->out->elementStart('li', array('id' => 'notice_text'));
$this->out->element('textarea', array('id' => 'notice_data-text',
'cols' => 35,
'rows' => 4,
'name' => 'content'),
($this->content) ? $this->content : '');
$this->out->elementEnd('li');
$this->out->elementEnd('ul');
}
/**
@ -156,14 +150,10 @@ class MessageForm extends Form
function formActions()
{
$this->out->elementStart('ul', 'form_actions');
$this->out->elementStart('li', array('id' => 'notice_submit'));
$this->out->element('input', array('id' => 'notice_action-submit',
'class' => 'submit',
'name' => 'message_send',
'type' => 'submit',
'value' => _('Send')));
$this->out->elementEnd('li');
$this->out->elementEnd('ul');
}
}

View File

@ -134,9 +134,6 @@ class NoticeForm extends Form
function formData()
{
$this->out->elementStart('ul', 'form_data');
$this->out->elementStart('li', array('id' => 'notice_text'));
$this->out->element('label', array('for' => 'notice_data-text'),
sprintf(_('What\'s up, %s?'), $this->user->nickname));
// XXX: vary by defined max size
@ -145,8 +142,6 @@ class NoticeForm extends Form
'rows' => 4,
'name' => 'status_textarea'),
($this->content) ? $this->content : '');
$this->out->elementEnd('li');
$this->out->elementEnd('ul');
$this->out->elementStart('dl', 'form_note');
$this->out->element('dt', null, _('Available characters'));
@ -168,14 +163,10 @@ class NoticeForm extends Form
function formActions()
{
$this->out->elementStart('ul', 'form_actions');
$this->out->elementStart('li', array('id' => 'notice_submit'));
$this->out->element('input', array('id' => 'notice_action-submit',
'class' => 'submit',
'name' => 'status_submit',
'type' => 'submit',
'value' => _('Send')));
$this->out->elementEnd('li');
$this->out->elementEnd('ul');
}
}

View File

@ -1,7 +1,7 @@
<?php
/*
* Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc.
* 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
@ -20,49 +20,92 @@
if (!defined('LACONICA')) { exit(1); }
function ping_broadcast_notice($notice) {
if (!$notice->is_local) {
return;
return true;
}
# Array of servers, URL => type
$notify = common_config('ping', 'notify');
$profile = $notice->getProfile();
$tags = ping_notice_tags($notice);
foreach ($notify as $notify_url => $type) {
switch ($type) {
case 'xmlrpc':
case 'extended':
$req = xmlrpc_encode_request('weblogUpdates.ping',
array($profile->nickname, # site name
common_local_url('showstream',
common_local_url('showstream',
array('nickname' => $profile->nickname)),
common_local_url('shownotice',
array('notice' => $notice->id)),
common_local_url('userrss',
common_local_url('userrss',
array('nickname' => $profile->nickname)),
$tags));
# We re-use this tool's fetcher, since it's pretty good
$fetcher = Auth_Yadis_Yadis::getHTTPFetcher();
if (!$fetcher) {
common_log(LOG_WARNING, 'Failed to initialize Yadis fetcher.', __FILE__);
return false;
}
$result = $fetcher->post($notify_url,
$req);
$context = stream_context_create(array('http' => array('method' => "POST",
'header' =>
"Content-Type: text/xml\r\n".
"User-Agent: Laconica/".LACONICA_VERSION."\r\n",
'content' => $req)));
$file = file_get_contents($notify_url, false, $context);
if ($file === false || mb_strlen($file) == 0) {
common_log(LOG_WARNING,
"XML-RPC empty results for ping ($notify_url, $notice->id) ");
continue;
}
$response = xmlrpc_decode($file);
if (xmlrpc_is_fault($response)) {
common_log(LOG_WARNING,
"XML-RPC error for ping ($notify_url, $notice->id) ".
"$response[faultString] ($response[faultCode])");
} else {
common_log(LOG_INFO,
"Ping success for $notify_url $notice->id");
}
break;
case 'get':
case 'post':
case 'post':
$args = array('name' => $profile->nickname,
'url' => common_local_url('showstream',
array('nickname' => $profile->nickname)),
'changesURL' => common_local_url('userrss',
array('nickname' => $profile->nickname)));
$fetcher = Auth_Yadis_Yadis::getHTTPFetcher();
if ($type === 'get') {
$result = $fetcher->get($notify_url . '?' . http_build_query($args),
array('User-Agent: Laconica/'.LACONICA_VERSION));
} else {
$result = $fetcher->post($notify_url,
http_build_query($args),
array('User-Agent: Laconica/'.LACONICA_VERSION));
}
if ($result->status != '200') {
common_log(LOG_WARNING,
"Ping error for '$notify_url' ($notice->id): ".
"$result->body");
} else {
common_log(LOG_INFO,
"Ping success for '$notify_url' ($notice->id): ".
"'$result->body'");
}
break;
default:
common_log(LOG_WARNING, 'Unknown notify type for ' . $notify_url . ': ' . $type);
}
}
}
return true;
}
function ping_notice_tags($notice) {
$tag = new Notice_tag();
$tag->notice_id = $notice->id;

View File

@ -89,7 +89,7 @@ class ProfileList extends Widget
'id' => 'profile-' . $this->profile->id));
$user = common_current_user();
$is_own = !is_null($user) && isset($this->user) && ($user->id === $this->user->id);
$is_own = !is_null($user) && isset($this->owner) && ($user->id === $this->owner->id);
$this->out->elementStart('div', 'entity_profile vcard');
@ -109,7 +109,7 @@ class ProfileList extends Widget
$this->out->elementEnd('span');
$this->out->elementEnd('a');
if ($this->profile->fullname !== '') {
if (!empty($this->profile->fullname)) {
$this->out->elementStart('dl', 'entity_fn');
$this->out->element('dt', null, 'Full name');
$this->out->elementStart('dd');
@ -119,7 +119,7 @@ class ProfileList extends Widget
$this->out->elementEnd('dd');
$this->out->elementEnd('dl');
}
if ($this->profile->location !== '') {
if (!empty($this->profile->location)) {
$this->out->elementStart('dl', 'entity_location');
$this->out->element('dt', null, _('Location'));
$this->out->elementStart('dd', 'label');
@ -127,7 +127,7 @@ class ProfileList extends Widget
$this->out->elementEnd('dd');
$this->out->elementEnd('dl');
}
if ($this->profile->homepage !== '') {
if (!empty($this->profile->homepage)) {
$this->out->elementStart('dl', 'entity_url');
$this->out->element('dt', null, _('URL'));
$this->out->elementStart('dd');
@ -138,7 +138,7 @@ class ProfileList extends Widget
$this->out->elementEnd('dd');
$this->out->elementEnd('dl');
}
if ($this->profile->bio !== '') {
if (!empty($this->profile->bio)) {
$this->out->elementStart('dl', 'entity_note');
$this->out->element('dt', null, _('Note'));
$this->out->elementStart('dd', 'note');
@ -194,11 +194,12 @@ class ProfileList extends Widget
$this->out->elementStart('ul');
if (!$is_own) {
# XXX: special-case for user looking at own
# subscriptions page
// Is this a logged-in user, looking at someone else's
// profile?
if (!empty($user) && $this->profile->id != $user->id) {
$this->out->elementStart('li', 'entity_subscribe');
if (!is_null($user) && $user->isSubscribed($this->profile)) {
if ($user->isSubscribed($this->profile)) {
$usf = new UnsubscribeForm($this->out, $this->profile);
$usf->show();
} else {
@ -207,6 +208,9 @@ class ProfileList extends Widget
}
$this->out->elementEnd('li');
$this->out->elementStart('li', 'entity_block');
if ($user->id == $this->owner->id) {
$this->showBlockForm();
}
$this->out->elementEnd('li');
}

View File

@ -68,8 +68,8 @@ class Router
}
}
function initialize() {
function initialize()
{
$m = Net_URL_Mapper::getInstance();
// In the "root"
@ -136,10 +136,17 @@ class Router
foreach (array('group', 'people', 'notice') as $s) {
$m->connect('search/'.$s, array('action' => $s.'search'));
$m->connect('search/'.$s.'?q=:q', array('action' => $s.'search'), array('q' => '.+'));
$m->connect('search/'.$s.'?q=:q',
array('action' => $s.'search'),
array('q' => '.+'));
}
// The second of these is needed to make the link work correctly
// when inserted into the page. The first is needed to match the
// route on the way in. Seems to be another Net_URL_Mapper bug to me.
$m->connect('search/notice/rss', array('action' => 'noticesearchrss'));
$m->connect('search/notice/rss?q=:q', array('action' => 'noticesearchrss'),
array('q' => '.+'));
// notice
@ -259,8 +266,8 @@ class Router
foreach (array('xml', 'json', 'rss', 'atom') as $e) {
$m->connect('api/direct_messages/sent.'.$e,
array('action' => 'api',
'apiaction' => 'direct_messages',
'method' => 'sent.'.$e));
'apiaction' => 'direct_messages',
'method' => 'sent.'.$e));
}
$m->connect('api/direct_messages/destroy/:argument',
@ -324,9 +331,9 @@ class Router
foreach (array('xml', 'json', 'rss', 'atom') as $e) {
$m->connect('api/favorites.'.$e,
array('action' => 'api',
'apiaction' => 'favorites',
'method' => 'favorites.'.$e));
array('action' => 'api',
'apiaction' => 'favorites',
'method' => 'favorites.'.$e));
}
// notifications
@ -411,7 +418,7 @@ class Router
$match = $this->m->match($path);
} catch (Net_URL_Mapper_InvalidException $e) {
common_log(LOG_ERR, "Problem getting route for $path - " .
$e->getMessage());
$e->getMessage());
$cac = new ClientErrorAction("Page not found.", 404);
$cac->showPage();
}
@ -429,6 +436,17 @@ class Router
$args = $action_arg;
}
return $this->m->generate($args, $params, $fragment);
$url = $this->m->generate($args, $params, $fragment);
// Due to a bug in the Net_URL_Mapper code, the returned URL may
// contain a malformed query of the form ?p1=v1?p2=v2?p3=v3. We
// repair that here rather than modifying the upstream code...
$qpos = strpos($url, '?');
if ($qpos !== false) {
$url = substr($url, 0, $qpos+1) .
str_replace('?', '&', substr($url, $qpos+1));
}
return $url;
}
}

View File

@ -94,11 +94,11 @@ class Rss10Action extends Action
function handle($args)
{
// Get the list of notices
$this->notices = $this->getNotices();
// Parent handling, including cache check
parent::handle($args);
$this->showRss($this->limit);
// Get the list of notices
$this->notices = $this->getNotices($this->limit);
$this->showRss();
}
/**
@ -132,15 +132,13 @@ class Rss10Action extends Action
return null;
}
function showRss($limit=0)
function showRss()
{
$notices = $this->getNotices($limit);
$this->initRss();
$this->showChannel($notices);
$this->showChannel();
$this->showImage();
foreach ($notices as $n) {
foreach ($this->notices as $n) {
$this->showItem($n);
}
@ -148,7 +146,7 @@ class Rss10Action extends Action
$this->endRss();
}
function showChannel($notices)
function showChannel()
{
$channel = $this->getChannel();
@ -167,7 +165,7 @@ class Rss10Action extends Action
$this->elementStart('items');
$this->elementStart('rdf:Seq');
foreach ($notices as $notice) {
foreach ($this->notices as $notice) {
$this->element('sioct:MicroblogPost', array('rdf:resource' => $notice->uri));
}

View File

@ -74,7 +74,7 @@ class SphinxSearch extends SearchEngine
{
//FIXME without LARGEST_POSSIBLE, the most recent results aren't returned
// this probably has a large impact on performance
$LARGEST_POSSIBLE = 1e6;
$LARGEST_POSSIBLE = 1e6;
if ($rss) {
$this->sphinx->setLimits($offset, $count, $count, $LARGEST_POSSIBLE);
@ -109,12 +109,25 @@ class MySQLSearch extends SearchEngine
{
function query($q)
{
if ('identica_people' === $this->table)
return $this->target->whereAdd('MATCH(nickname, fullname, location, bio, homepage) ' .
'against (\''.addslashes($q).'\')');
if ('identica_notices' === $this->table)
return $this->target->whereAdd('MATCH(content) ' .
'against (\''.addslashes($q).'\')');
if ('identica_people' === $this->table) {
$this->target->whereAdd('MATCH(nickname, fullname, location, bio, homepage) ' .
'AGAINST (\''.addslashes($q).'\' IN BOOLEAN MODE)');
if (strtolower($q) != $q) {
$this->target->whereAdd('MATCH(nickname, fullname, location, bio, homepage) ' .
'AGAINST (\''.addslashes(strtolower($q)).'\' IN BOOLEAN MODE)', 'OR');
}
return true;
} else if ('identica_notices' === $this->table) {
$this->target->whereAdd('MATCH(content) ' .
'AGAINST (\''.addslashes($q).'\' IN BOOLEAN MODE)');
if (strtolower($q) != $q) {
$this->target->whereAdd('MATCH(content) ' .
'AGAINST (\''.addslashes(strtolower($q)).'\' IN BOOLEAN MODE)', 'OR');
}
return true;
} else {
throw new ServerException('Unknown table: ' . $this->table);
}
}
}
@ -122,10 +135,13 @@ class PGSearch extends SearchEngine
{
function query($q)
{
if ('identica_people' === $this->table)
if ('identica_people' === $this->table) {
return $this->target->whereAdd('textsearch @@ plainto_tsquery(\''.addslashes($q).'\')');
if ('identica_notices' === $this->table)
} else if ('identica_notices' === $this->table) {
return $this->target->whereAdd('to_tsvector(\'english\', content) @@ plainto_tsquery(\''.addslashes($q).'\')');
} else {
throw new ServerException('Unknown table: ' . $this->table);
}
}
}

View File

@ -238,21 +238,6 @@ class TwitterapiAction extends Action
$this->elementEnd('item');
}
function show_twitter_atom_entry($entry)
{
$this->elementStart('entry');
$this->element('title', null, $entry['title']);
$this->element('content', array('type' => 'html'), $entry['content']);
$this->element('id', null, $entry['id']);
$this->element('published', null, $entry['published']);
$this->element('updated', null, $entry['updated']);
$this->element('link', array('href' => $entry['link'], 'rel' => 'alternate', 'type' => 'text/html'), null);
$this->elementStart('author');
$this->element('name', null, $entry['author']);
$this->elementEnd('author');
$this->elementEnd('entry');
}
function show_json_objects($objects)
{
print(json_encode($objects));
@ -383,7 +368,7 @@ class TwitterapiAction extends Action
}
if (!is_null($selfuri)) {
$this->element('link', array('href' => $selfuri,
$this->element('link', array('href' => $selfuri,
'rel' => 'self', 'type' => 'application/atom+xml'), null);
}
@ -392,13 +377,11 @@ class TwitterapiAction extends Action
if (is_array($notice)) {
foreach ($notice as $n) {
$entry = $this->twitter_rss_entry_array($n);
$this->show_twitter_atom_entry($entry);
$this->raw($n->asAtomEntry());
}
} else {
while ($notice->fetch()) {
$entry = $this->twitter_rss_entry_array($notice);
$this->show_twitter_atom_entry($entry);
$this->raw($notice->asAtomEntry());
}
}
@ -578,13 +561,16 @@ class TwitterapiAction extends Action
function init_twitter_atom()
{
$this->startXML();
$this->elementStart('feed', array('xmlns' => 'http://www.w3.org/2005/Atom', 'xml:lang' => 'en-US'));
// FIXME: don't hardcode the language here!
$this->elementStart('feed', array('xmlns' => 'http://www.w3.org/2005/Atom',
'xml:lang' => 'en-US',
'xmlns:thr' => 'http://purl.org/syndication/thread/1.0'));
}
function end_twitter_atom()
{
$this->endXML();
$this->elementEnd('feed');
$this->endXML();
}
function show_profile($profile, $content_type='xml', $notice=null)

View File

@ -34,7 +34,7 @@ require_once(INSTALLDIR . '/lib/queuehandler.php');
set_error_handler('common_error_handler');
class PingQueueHandler extends QueueHandler {
function transport() {
return 'ping';
}
@ -47,7 +47,7 @@ class PingQueueHandler extends QueueHandler {
function handle_notice($notice) {
return ping_broadcast_notice($notice);
}
function finish() {
}
}

View File

@ -150,7 +150,9 @@ font-weight:bold;
#form_openid_login legend,
#form_search legend,
#form_invite legend,
#form_notice_delete legend {
#form_notice_delete legend,
#form_password_recover legend,
#form_password_change legend {
display:none;
}
@ -419,6 +421,7 @@ padding:0;
display:none;
}
#form_notice textarea {
float:left;
border-radius:7px;
-moz-border-radius:7px;
-webkit-border-radius:7px;
@ -429,30 +432,19 @@ padding:7px 7px 16px 7px;
}
#form_notice label {
display:block;
float:left;
font-size:1.3em;
margin-bottom:7px;
}
#form_notice .form_data li {
float:left;
}
#form_notice #notice_attach_file label,
#form_notice #notice_submit label {
display:none;
}
#form_notice #notice_attachment {
margin-top:25px;
margin-left:4px;
}
#form_notice .form_note {
position:absolute;
top:99px;
right:98px;
z-index:9;
}
#form_notice .form_note dt {
font-weight:bold;
display:none;
@ -462,42 +454,19 @@ font-weight:bold;
line-height:1.15;
padding:1px 2px;
}
#form_notice #notice_data-attach_view {
position:absolute;
top:25px;
right:30px;
margin-left:4px;
padding:0;
width:16px;
height:16px;
border:0;
text-indent:-9999px;
}
#form_notice .form_actions {
#form_notice #notice_action-submit {
width:60px;
padding:8px;
position:absolute;
bottom:0;
right:0;
}
#form_notice .form_actions input.submit {
width:60px;
padding:8px;
}
#form_notice li {
margin-bottom:0;
}
#form_notice #notice_to {
margin-bottom:7px;
}
#notice_to label {
float:left;
margin-right:18px;
#form_notice label[for=to] {
margin-top:11px;
}
#notice_to select {
#form_notice select[id=to] {
margin-bottom:7px;
margin-left:18px;
float:left;
}
/*end FORM NOTICE*/

View File

@ -9,3 +9,6 @@ margin-left:0;
.entity_profile .entity_depiction {
margin-bottom:123px;
}
.notice div.entry-content {
width:63%;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

View File

@ -94,6 +94,11 @@ color:#333;
#form_notice.warning #notice_text-count {
color:#000;
}
#form_notice.processing #notice_action-submit {
background:#fff url(../../base/images/icons/icon_processing.gif) no-repeat 47% 47%;
cursor:wait;
text-indent:-9999px;
}
#nav_register a {

View File

@ -94,7 +94,11 @@ color:#333;
#form_notice.warning #notice_text-count {
color:#000;
}
#form_notice.processing #notice_action-submit {
background:#fff url(../../base/images/icons/icon_processing.gif) no-repeat 47% 47%;
cursor:wait;
text-indent:-9999px;
}
#nav_register a {
text-decoration:none;