1
0
Fork 0

Merge branch 'newui' of github.com:fabrixxm/friendika into newui

This commit is contained in:
fabrixxm 2011-09-05 21:05:24 +02:00
commit 2f5a34ad17
159 changed files with 5101 additions and 2385 deletions

1
.gitignore vendored
View file

@ -7,3 +7,4 @@ include/jquery-1.4.2.min.js
*.version*
favicon.*
home.html
*~

View file

@ -17,7 +17,7 @@ function calc_uninstall() {
}
function calc_app_menu($a,&$b) {
$b['app_menu'] .= '<div class="app-title"><a href="calc">Calculator</a></div>';
$b['app_menu'][] = Array('url'=>'calc', 'name'=>'Calculator');
}

View file

@ -15,7 +15,7 @@ function convert_uninstall() {
}
function convert_app_menu($a,&$b) {
$b['app_menu'] .= '<div class="app-title"><a href="convert">Units Conversion</a></div>';
$b['app_menu'][] = Array('url'=>'convert', 'name'=>'Units Conversion');
}

View file

@ -33,3 +33,7 @@ long posts truncated - with a link to view the full post.
Facebook contacts will not be able to view private photos, as they are not able to
authenticate to your site to establish identity. We will address this
in a future release.
Info: please make sure that you understand all aspects due to Friendika's
default licence which is: Creative Commons Attribution 3.0 (further info:
http://creativecommons.org/licenses/by/3.0/ )

View file

@ -273,6 +273,10 @@ function facebook_post(&$a) {
$no_linking = get_pconfig($uid,'facebook','no_linking');
$no_wall = ((x($_POST,'facebook_no_wall')) ? intval($_POST['facebook_no_wall']) : 0);
set__pconfig($uid,'facebook','no_wall',$no_wall);
$linkvalue = ((x($_POST,'facebook_linking')) ? intval($_POST['facebook_linking']) : 0);
set_pconfig($uid,'facebook','no_linking', (($linkvalue) ? 0 : 1));
@ -359,12 +363,11 @@ function facebook_content(&$a) {
$checked = (($no_linking) ? '' : ' checked="checked" ');
$o .= '<input type="checkbox" name="facebook_linking" value="1"' . $checked . '/>' . ' ' . t('Link all your Facebook friends and conversations') . EOL ;
$hidden = (($a->user['hidewall'] || get_config('system','block_public')) ? true : false);
if(! $hidden) {
$o .= EOL;
$o .= t('Warning: Your Facebook privacy settings can not be imported.') . EOL;
$o .= t('Linked Facebook items <strong>may</strong> be publicly visible, depending on your privacy settings for this website/account.') . EOL;
}
$no_wall = get_pconfig(local_user(),'facebook','no_wall');
$checked = (($no_wall) ? ' checked="checked" ' : '');
$o .= '<input type="checkbox" name="facebook_no_wall" value="1"' . $checked . '/>' . ' ' . t('Do not link your Facebook profile wall posts - as these could be visible to people that would not be able to see them on Facebook.') . EOL ;
$o .= '<input type="submit" name="submit" value="' . t('Submit') . '" /></form></div>';
}
@ -766,12 +769,13 @@ function fb_consume_all($uid) {
if(! $access_token)
return;
$s = fetch_url('https://graph.facebook.com/me/feed?access_token=' . $access_token);
if($s) {
$j = json_decode($s);
logger('fb_consume_stream: wall: ' . print_r($j,true), LOGGER_DATA);
fb_consume_stream($uid,$j,true);
if(! get_pconfig($uid,'facebook','no_wall')) {
$s = fetch_url('https://graph.facebook.com/me/feed?access_token=' . $access_token);
if($s) {
$j = json_decode($s);
logger('fb_consume_stream: wall: ' . print_r($j,true), LOGGER_DATA);
fb_consume_stream($uid,$j,true);
}
}
$s = fetch_url('https://graph.facebook.com/me/home?access_token=' . $access_token);
if($s) {

View file

@ -7,7 +7,7 @@ License: 3-clause BSD license (same as Friendika)
About
This plugin adds an Impressum block to the /friendika page with informations
about the page operator/owner and how to countact you in case of any questions.
about the page operator/owner and how to contact you in case of any questions.
In the notes and postal fields you can use HTML tags for formatting.

View file

@ -22,7 +22,7 @@ function sniper_uninstall() {
}
function sniper_app_menu($a,&$b) {
$b['app_menu'] .= '<div class="app-title"><a href="sniper">Hot Shot Sniper</a></div>';
$b['app_menu'][] = Array('url'=>'sniper', 'name'=>'Hot Shot Sniper');
}

View file

@ -3,30 +3,30 @@ by Tobias Diekershoff
tobias.diekershoff(at)gmx.net
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This addon is currently in under development. If you have any problem !!
!! This addon is currently under development. If you have any problem !!
!! with it, please contact the Author. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
With this addon to Friendika you can give your user the possibility to post
their public messages to any StatusNet instance like identi.ca for example. The
messages will be strapped their rich context and shortened to to the character
their public messages to any StatusNet instance (like identi.ca for example).
The messages will be strapped their rich context and shortened to to the character
limit of the StatusNet instance in question if necessary. If shortening of the
message was performed a link will be added to the notice pointing to the
original message on your server.
There is a similar plugin to forward public messages to Twitter Twitter Plugin.
There is a similar plugin to forward public messages to Twitter: Twitter Plugin.
Online version of this document: http://ur1.ca/35mpb
___ Requirements ___
Due to the distributed nature of the StatusNet network, each user who wishes to
forward public messages to a StatusNet account has get the OAuth credentials
for themselves, which makes this addon a little bit more user unfriendly then
the Twitter Plugin is. Nothing to geeky though!
forward public messages to a StatusNet account has to get the OAuth credentials
for themselves, which makes this addon a little bit more user unfriendly than
the Twitter Plugin is. Nothing too geeky though!
The inclusion of a shorturl for the original posting in cases when the message
was longer then the maximal allowed notice length requires it, that you have
was longer than the maximal allowed notice length requires it, that you have
PHP5+ and curl on your server.
Where to find
@ -58,7 +58,7 @@ To get the OAuth Consumer key pair the user has to (a) ask her Friendika admin
if a pair already exists or (b) has to register the Friendika server as a
client application on the StatusNet server. This can be done from the account
settings under "Connect -> Connections -> Register an OAuth client application
-> Register new application".
-> Register a new application".
During the registration of the OAuth client remember the following:
* there is no callback url
@ -69,7 +69,7 @@ During the registration of the OAuth client remember the following:
After the required credentials for the application are stored in the
configuration you have to actually connect your Friendika account with
StatusNet. To do so follow the Sign in with StatusNet button, allow the access
and copy the security code into the addon configuration. Friendika will then
and copy the security code into the plugin configuration. Friendika will then
try to acquire the final OAuth credentials from the API, if successful the
addon settings will allow you to select to post your public messages to your
plugin settings will allow you to select to post your public messages to your
StatusNet account.

View file

@ -355,7 +355,10 @@ function statusnet_post_hook(&$a,&$b) {
logger('StatusNet post invoked');
if((local_user()) && (local_user() == $b['uid']) && (! $b['private']) && (!$b['parent']) ) {
if((local_user()) && (local_user() == $b['uid']) && (! $b['private'])) {
// mike 2-9-11 there was a restriction to only allow this for top level posts
// now relaxed so should allow one's own comments to be forwarded through the connector as well.
// Status.Net is not considered a private network
if($b['prvnets'])

View file

@ -17,7 +17,7 @@ function tictac_uninstall() {
}
function tictac_app_menu($a,&$b) {
$b['app_menu'] .= '<div class="app-title"><a href="tictac">' . t('Three Dimensional Tic-Tac-Toe') . '</a></div>';
$b['app_menu'][] = Array('url'=>'tictac', 'name'=>'Three Dimensional Tic-Tac-Toe');
}

View file

@ -3,7 +3,7 @@ By Tobias Diekershoff
tobias.diekershoff(at)gmx.net
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This addon is currently in under development. If you have any problem !!
!! This addon is currently under development. If you have any problem !!
!! with it, please contact the Author. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@ -29,7 +29,7 @@ After you registered the application you get an OAuth consumer key / secret
pair that identifies your app, you will need them for configuration.
The inclusion of a shorturl for the original posting in cases when the
message was longer then 140 characters requires it, that you have *PHP5+* and
message was longer than 140 characters requires it, that you have *PHP5+* and
*curl* on your server.
___ Where to find ___
@ -51,19 +51,19 @@ To activate this addon add @twitter@ to the list of active addons in your
.htconfig.php file
$a->config['system']['addon'] = "twitter, ..."
Afterwards you need to add your OAuth consumer key / secret pair to it by
adding the following to lines
adding the following two lines
$a->config['twitter']['consumerkey'] = 'your consumer KEY here';
$a->config['twitter']['consumersecret'] = 'your consumer SECRET here';
When this is done your user can now configure their Twitter connection at
"Settings -> Addon Settings" and enable the forwarding of their *public*
"Settings -> Plugin Settings" and enable the forwarding of their *public*
messages to Twitter.
__ User Configuration __
When the OAuth consumer informations are correctly placed into the
configuration file and a user visits the "Addon Settings" page they can now
configuration file and a user visits the "Plugin Settings" page they can now
connect to Twitter. To do so one has to follow the _Sign in with Twitter_
button (the page will be opened in a new browser window/tab) and get a PIN from
Twitter. This PIN has to be entered on the settings page. After submitting the
@ -71,7 +71,7 @@ PIN the plugin will get OAuth credentials identifying this user from the
Friendika account.
If this first step was successful the Twitter configuration will be changed
on the "Addon Settings" page displaying two check boxes. One to enable/disable
on the "Plugin Settings" page displaying two check boxes. One to enable/disable
the forwarding of *all public* postings to Twitter and one to clear the
personal configuration from the Twitter credentials.

View file

@ -4,7 +4,7 @@ function like_widget_name() {
return "Shows likes";
}
function like_widget_help() {
return "Search first item wich contains <em>KEY</em> and print like/dislike count";
return "Search first item which contains <em>KEY</em> and print like/dislike count";
}
function like_widget_args(){

169
boot.php
View file

@ -8,9 +8,9 @@ require_once("include/pgettext.php");
require_once('include/nav.php');
define ( 'FRIENDIKA_VERSION', '2.2.1083' );
define ( 'FRIENDIKA_VERSION', '2.2.1093' );
define ( 'DFRN_PROTOCOL_VERSION', '2.21' );
define ( 'DB_UPDATE_VERSION', 1082 );
define ( 'DB_UPDATE_VERSION', 1087 );
define ( 'EOL', "<br />\r\n" );
define ( 'ATOM_TIME', 'Y-m-d\TH:i:s\Z' );
@ -246,7 +246,7 @@ class App {
public $timezone;
public $interactive = true;
public $plugins;
public $apps;
public $apps = Array();
public $identities;
private $scheme;
@ -675,6 +675,8 @@ function login($register = false) {
'$lostlink' => $lostlink
));
call_hooks('login_hook',$o);
return $o;
}}
@ -719,14 +721,16 @@ function remote_user() {
if(! function_exists('notice')) {
function notice($s) {
$a = get_app();
if(! x($_SESSION,'sysmsg')) $_SESSION['sysmsg'] = array();
if($a->interactive)
$_SESSION['sysmsg'] .= $s;
$_SESSION['sysmsg'][] = $s;
}}
if(! function_exists('info')) {
function info($s) {
$a = get_app();
if(! x($_SESSION,'sysmsg_info')) $_SESSION['sysmsg_info'] = array();
if($a->interactive)
$_SESSION['sysmsg_info'] .= $s;
$_SESSION['sysmsg_info'][] = $s;
}}
@ -808,8 +812,8 @@ function profile_load(&$a, $nickname, $profile = 0) {
$a->page['aside'] .= profile_sidebar($a->profile, $block);
if(! $block)
$a->page['aside'] .= contact_block();
/*if(! $block)
$a->page['aside'] .= contact_block();*/
return;
}}
@ -837,132 +841,105 @@ function profile_sidebar($profile, $block = 0) {
$a = get_app();
$o = '';
$location = '';
$location = false;
$address = false;
$pdesc = true;
if((! is_array($profile)) && (! count($profile)))
return $o;
call_hooks('profile_sidebar_enter', $profile);
$fullname = '<div class="fn">' . $profile['name'] . '</div>';
$pdesc = '<div class="title">' . $profile['pdesc'] . '</div>';
$tabs = '';
$photo = '<div id="profile-photo-wrapper"><img class="photo" width="175" height="175" src="' . $profile['photo'] . '" alt="' . $profile['name'] . '" /></div>';
// don't show connect link to yourself
$connect = (($profile['uid'] != local_user()) ? '<li><a id="dfrn-request-link" href="dfrn_request/' . $profile['nickname'] . '">' . t('Connect') . '</a></li>' : '');
$connect = (($profile['uid'] != local_user()) ? t('Connect') : False);
// don't show connect link to authenticated visitors either
if((remote_user()) && ($_SESSION['visitor_visiting'] == $profile['uid']))
$connect = '';
$connect = False;
// show edit profile to yourself
if ($profile['uid'] == local_user()) {
$profile['edit'] = array($a->get_baseurl(). '/profiles', t('Profiles'),"", t('Manage/edit profiles'));
$r = q("SELECT * FROM `profile` WHERE `uid` = %d",
local_user());
$profile['menu'] = array(
'chg_photo' => t('Change profile photo'),
'cr_new' => t('Create New Profile'),
'entries' => array(),
);
if(count($r)) {
foreach($r as $rr) {
$profile['menu']['entries'][] = array(
'photo' => $rr['thumb'],
'id' => $rr['id'],
'alt' => t('Profile Image'),
'profile_name' => $rr['profile-name'],
'visible' => (($rr['is-default']) ? '<strong>' . t('visible to everybody') . '</strong>'
: '<a href="' . $a->get_baseurl() . '/profperm/' . $rr['id'] . '" />' . t('Edit visibility') . '</a>')
);
}
}
}
if((x($profile,'address') == 1)
|| (x($profile,'locality') == 1)
|| (x($profile,'region') == 1)
|| (x($profile,'postal-code') == 1)
|| (x($profile,'country-name') == 1))
$address = true;
$location = t('Location:');
if($address) {
$location .= '<div class="location"><span class="location-label">' . t('Location:') . '</span> <div class="adr">';
$location .= ((x($profile,'address') == 1) ? '<div class="street-address">' . $profile['address'] . '</div>' : '');
$location .= (((x($profile,'locality') == 1) || (x($profile,'region') == 1) || (x($profile,'postal-code') == 1))
? '<span class="city-state-zip"><span class="locality">' . $profile['locality'] . '</span>'
. ((x($profile['locality']) == 1) ? t(', ') : '')
. '<span class="region">' . $profile['region'] . '</span>'
. ' <span class="postal-code">' . $profile['postal-code'] . '</span></span>' : '');
$location .= ((x($profile,'country-name') == 1) ? ' <span class="country-name">' . $profile['country-name'] . '</span>' : '');
$location .= '</div></div><div class="profile-clear"></div>';
}
$gender = ((x($profile,'gender') == 1) ? t('Gender:') : False);
$gender = ((x($profile,'gender') == 1) ? '<div class="mf"><span class="gender-label">' . t('Gender:') . '</span> <span class="x-gender">' . $profile['gender'] . '</span></div><div class="profile-clear"></div>' : '');
$marital = ((x($profile,'marital') == 1) ? t('Status:') : False);
$pubkey = ((x($profile,'pubkey') == 1) ? '<div class="key" style="display:none;">' . $profile['pubkey'] . '</div>' : '');
$marital = ((x($profile,'marital') == 1) ? '<div class="marital"><span class="marital-label"><span class="heart">&hearts;</span> ' . t('Status:') . ' </span><span class="marital-text">' . $profile['marital'] . '</span></div><div class="profile-clear"></div>' : '');
$homepage = ((x($profile,'homepage') == 1) ? '<div class="homepage"><span class="homepage-label">' . t('Homepage:') . ' </span><span class="homepage-url">' . linkify($profile['homepage']) . '</span></div><div class="profile-clear"></div>' : '');
$homepage = ((x($profile,'homepage') == 1) ? t('Homepage:') : False);
if(($profile['hidewall'] || $block) && (! local_user()) && (! remote_user())) {
$location = $pdesc = $connect = $gender = $marital = $homepage = '';
$location = $pdesc = $connect = $gender = $marital = $homepage = False;
}
$podloc = $a->get_baseurl();
$searchable = (($profile['publish'] && $profile['net-publish']) ? 'true' : 'false' );
$nickname = $profile['nickname'];
$photo300 = $a->get_baseurl() . '/photo/custom/300/' . $profile['uid'] . '.jpg';
$photo100 = $a->get_baseurl() . '/photo/custom/100/' . $profile['uid'] . '.jpg';
$photo50 = $a->get_baseurl() . '/photo/custom/50/' . $profile['uid'] . '.jpg';
$diaspora = array(
'podloc' => $a->get_baseurl(),
'searchable' => (($profile['publish'] && $profile['net-publish']) ? 'true' : 'false' ),
'nickname ' => $profile['nickname'],
'fullname' => $profile['name'],
'photo300' => $a->get_baseurl() . '/photo/custom/300/' . $profile['uid'] . '.jpg',
'photo100' => $a->get_baseurl() . '/photo/custom/100/' . $profile['uid'] . '.jpg',
'photo50' => $a->get_baseurl() . '/photo/custom/50/' . $profile['uid'] . '.jpg',
);
$diaspora_vcard = <<< EOT
if (!$block){
$contact_block = contact_block();
}
<div style="display:none;">
<dl class='entity_nickname'>
<dt>Nickname</dt>
<dd>
<a class="nickname url uid" href="$podloc/" rel="me">$nickname</a>
</dd>
</dl>
<dl class='entity_fn'>
<dt>Full name</dt>
<dd>
<span class='fn'>$fullname</span>
</dd>
</dl>
<dl class="entity_url">
<dt>URL</dt>
<dd>
<a class="url" href="$podloc/" id="pod_location" rel="me">$podloc/</a>
</dd>
</dl>
<dl class="entity_photo">
<dt>Photo</dt>
<dd>
<img class="photo avatar" height="300px" width="300px" src="$photo300">
</dd>
</dl>
<dl class="entity_photo_medium">
<dt>Photo</dt>
<dd>
<img class="photo avatar" height="100px" width="100px" src="$photo100">
</dd>
</dl>
<dl class="entity_photo_small">
<dt>Photo</dt>
<dd>
<img class="photo avatar" height="50px" width="50px" src="$photo50">
</dd>
</dl>
<dl class="entity_searchable">
<dt>Searchable</dt>
<dd>
<span class="searchable">$searchable</span>
</dd>
</dl>
</div>
EOT;
$tpl = get_markup_template('profile_vcard.tpl');
$o .= replace_macros($tpl, array(
'$fullname' => $fullname,
'$pdesc' => $pdesc,
'$tabs' => $tabs,
'$photo' => $photo,
'$profile' => $profile,
'$connect' => $connect,
'$location' => $location,
'$gender' => $gender,
'$pubkey' => $pubkey,
'$pdesc' => $pdesc,
'$marital' => $marital,
'$homepage' => $homepage,
'$diaspora' => $diaspora_vcard
'$diaspora' => $diaspora,
'$contact_block' => $contact_block,
));

View file

@ -58,6 +58,7 @@ CREATE TABLE IF NOT EXISTS `contact` (
`network` char(255) NOT NULL,
`name` char(255) NOT NULL,
`nick` char(255) NOT NULL,
`attag` char(255) NOT NULL,
`photo` text NOT NULL,
`thumb` text NOT NULL,
`micro` text NOT NULL,
@ -205,6 +206,7 @@ CREATE TABLE IF NOT EXISTS `item` (
`pubmail` tinyint(1) NOT NULL DEFAULT '0',
`visible` tinyint(1) NOT NULL DEFAULT '0',
`starred` tinyint(1) NOT NULL DEFAULT '0',
`bookmark` tinyint(1) NOT NULL DEFAULT '0',
`unseen` tinyint(1) NOT NULL DEFAULT '1',
`deleted` tinyint(1) NOT NULL DEFAULT '0',
`last-child` tinyint(1) unsigned NOT NULL DEFAULT '1',
@ -606,3 +608,17 @@ INDEX ( `iid` )
) ENGINE = MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `deliverq` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`cmd` CHAR( 32 ) NOT NULL ,
`item` INT NOT NULL ,
`contact` INT NOT NULL
) ENGINE = MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `search` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`uid` INT NOT NULL ,
`term` CHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
INDEX ( `uid` ),
INDEX ( `term` )
) ENGINE = MyISAM DEFAULT CHARSET=utf8;

View file

@ -12,7 +12,7 @@ All three of these plugins require an account on the target network. In addition
**Site Configuration**
Plugins must be installed by the site administrator before they can be use. This is accomplished through the site
Plugins must be installed by the site administrator before they can be used. This is accomplished through the site
configuration file ".htconfig.php".
The configuration directive looks like:
@ -84,7 +84,7 @@ To get the OAuth Consumer key pair the user has to
(a) ask her Friendika admin if a pair already exists or
(b) has to register the Friendika server as a client application on the StatusNet server.
This can be done from the account settings under "Settings -> Connections -> Register an OAuth client application -> Register new application".
This can be done from the account settings under "Settings -> Connections -> Register an OAuth client application -> Register a new application".
During the registration of the OAuth client remember the following:
@ -133,8 +133,8 @@ d. Navigate to Set Web->Site URL & Domain -> Website Settings. Set Site URL
to yoursubdomain.yourdomain.com. Set Site Domain to your yourdomain.com.
Visit the Facebook Settings section of the "Settings->Plugin Settings" page.
and click 'Install Facebook Connector'.
Visit the Facebook Settings section of the "Settings->Plugin Settings" page.
And click 'Install Facebook Connector'.
This will ask you to login to Facebook and grant permission to the
plugin to do its stuff. Allow it to do so.

BIN
images/connect-bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 689 B

BIN
images/icons/10/add.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
images/icons/10/delete.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
images/icons/10/edit.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
images/icons/10/feed.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 535 B

BIN
images/icons/10/gear.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

BIN
images/icons/10/group.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 543 B

BIN
images/icons/10/info.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 B

BIN
images/icons/10/notice.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 471 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 478 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 369 B

BIN
images/icons/10/star.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
images/icons/10/user.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 534 B

BIN
images/icons/16/add.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

BIN
images/icons/16/delete.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
images/icons/16/edit.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
images/icons/16/feed.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 828 B

BIN
images/icons/16/gear.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
images/icons/16/group.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 852 B

BIN
images/icons/16/info.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 854 B

BIN
images/icons/16/notice.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 591 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 835 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 542 B

BIN
images/icons/16/star.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
images/icons/16/user.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 794 B

BIN
images/icons/22/add.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
images/icons/22/delete.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
images/icons/22/edit.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
images/icons/22/feed.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
images/icons/22/gear.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
images/icons/22/group.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
images/icons/22/info.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
images/icons/22/notice.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 780 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 721 B

BIN
images/icons/22/star.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

BIN
images/icons/22/user.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
images/icons/48/add.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
images/icons/48/delete.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
images/icons/48/edit.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
images/icons/48/feed.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
images/icons/48/gear.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

BIN
images/icons/48/group.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
images/icons/48/info.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
images/icons/48/notice.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
images/icons/48/star.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

BIN
images/icons/48/user.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
images/icons/add.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

BIN
images/icons/delete.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

BIN
images/icons/edit.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

BIN
images/icons/feed.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

BIN
images/icons/gear.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 886 B

BIN
images/icons/group.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

BIN
images/icons/info.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

14
images/icons/make.sh Normal file
View file

@ -0,0 +1,14 @@
sizes="10 16 22 48"
for s in $sizes
do
echo "=[ ${s}x${s} ]===="
[ -d $s ] || mkdir $s
for f in *.png
do
convert $f -resize ${s}x${s} $s/$f
echo -n "#"
done
echo
done
echo "Ok."

BIN
images/icons/notice.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
images/icons/notify_off.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 884 B

BIN
images/icons/notify_on.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 561 B

BIN
images/icons/star.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

BIN
images/icons/user.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

View file

@ -332,10 +332,12 @@ function probe_url($url, $mode = PROBE_NORMAL) {
if(! $url)
return $result;
$network = null;
$diaspora = false;
$diaspora_base = '';
$diaspora_guid = '';
$diaspora_key = '';
$has_lrdd = false;
$email_conversant = false;
$twitter = ((strpos($url,'twitter.com') !== false) ? true : false);
@ -352,6 +354,8 @@ function probe_url($url, $mode = PROBE_NORMAL) {
$links = lrdd($url);
if(count($links)) {
$has_lrdd = true;
logger('probe_url: found lrdd links: ' . print_r($links,true), LOGGER_DATA);
foreach($links as $link) {
if($link['@attributes']['rel'] === NAMESPACE_ZOT)
@ -493,7 +497,7 @@ function probe_url($url, $mode = PROBE_NORMAL) {
if($network !== NETWORK_ZOT && $network !== NETWORK_DFRN && $network !== NETWORK_MAIL) {
if($diaspora)
$network = NETWORK_DIASPORA;
else
elseif($has_lrdd)
$network = NETWORK_OSTATUS;
$priority = 0;
@ -637,7 +641,7 @@ function probe_url($url, $mode = PROBE_NORMAL) {
$vcard['nick'] = trim(substr($vcard['nick'],0,strpos($vcard['nick'],' ')));
}
if(! $network)
$network = 'feed';
$network = NETWORK_FEED;
if(! $priority)
$priority = 2;
}
@ -651,10 +655,14 @@ function probe_url($url, $mode = PROBE_NORMAL) {
if(! $profile)
$profile = $url;
// No human could be associated with this link, use the URL as the contact name
if(($network === NETWORK_FEED) && ($poll) && (! x($vcard,'fn')))
$vcard['fn'] = $url;
$vcard['fn'] = notags($vcard['fn']);
$vcard['nick'] = str_replace(' ','',notags($vcard['nick']));
$result['name'] = $vcard['fn'];
$result['nick'] = $vcard['nick'];
$result['url'] = $profile;

View file

@ -1,6 +1,7 @@
<?php
require_once("bbcode.php");
require_once("datetime.php");
require_once("conversation.php");
/*
* Twitter-Like API
@ -8,7 +9,7 @@
*/
$API = Array();
$called_api = Null;
function api_date($str){
//Wed May 23 06:01:13 +0000 2007
@ -103,9 +104,10 @@
* MAIN API ENTRY POINT *
**************************/
function api_call(&$a){
GLOBAL $API;
GLOBAL $API, $called_api;
foreach ($API as $p=>$info){
if (strpos($a->query_string, $p)===0){
$called_api= explode("/",$p);
#unset($_SERVER['PHP_AUTH_USER']);
if ($info['auth']===true && local_user()===false) {
api_login($a);
@ -131,7 +133,7 @@
return '<?xml version="1.0" encoding="UTF-8"?>'."\n".$r;
break;
case "json":
header ("Content-Type: application/json");
//header ("Content-Type: application/json");
foreach($r as $rr)
return json_encode($rr);
break;
@ -193,6 +195,7 @@
* Returns user info array.
*/
function api_get_user(&$a, $contact_id = Null){
global $called_api;
$user = null;
$extra_query = "";
@ -209,16 +212,20 @@
if(is_null($user) && x($_GET, 'screen_name')) {
$user = dbesc($_GET['screen_name']);
$extra_query = "AND `contact`.`nick` = '%s' ";
if (local_user()!==false) $extra_query .= "AND `contact`.`uid`=".intval(local_user());
}
if (is_null($user) && $a->argc > 3){
list($user, $null) = explode(".",$a->argv[3]);
if (is_null($user) && $a->argc > (count($called_api)-1)){
$argid = count($called_api);
list($user, $null) = explode(".",$a->argv[$argid]);
if(is_numeric($user)){
$user = intval($user);
$extra_query = "AND `contact`.`id` = %d ";
} else {
$user = dbesc($user);
$extra_query = "AND `contact`.`nick` = '%s' ";
if (local_user()!==false) $extra_query .= "AND `contact`.`uid`=".intval(local_user());
}
}
@ -301,6 +308,7 @@
}
$ret = Array(
'self' => intval($uinfo[0]['self']),
'uid' => intval($uinfo[0]['uid']),
'id' => intval($uinfo[0]['cid']),
'name' => $uinfo[0]['name'],
@ -321,7 +329,7 @@
'followers_count' => intval($countfollowers),
'favourites_count' => intval($starred),
'contributors_enabled' => false,
'follow_request_sent' => false,
'follow_request_sent' => true,
'profile_background_color' => 'cfe8f6',
'profile_text_color' => '000000',
'profile_link_color' => 'FF8500',
@ -616,6 +624,7 @@
$user_info = api_get_user($a);
// get last newtork messages
// params
$count = (x($_REQUEST,'count')?$_REQUEST['count']:20);
$page = (x($_REQUEST,'page')?$_REQUEST['page']-1:0);
@ -664,6 +673,12 @@
$user_info = api_get_user($a);
// get last newtork messages
logger("api_statuses_user_timeline: local_user: ". local_user() .
"\nuser_info: ".print_r($user_info, true) .
"\n_REQUEST: ".print_r($_REQUEST, true),
LOGGER_DEBUG);
// params
$count = (x($_REQUEST,'count')?$_REQUEST['count']:20);
$page = (x($_REQUEST,'page')?$_REQUEST['page']-1:0);
@ -672,6 +687,7 @@
$start = $page*$count;
if ($user_info['self']==1) $sql_extra = "AND `item`.`wall` = 1 ";
$r = q("SELECT `item`.*, `item`.`id` AS `item_id`,
`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`,
@ -679,14 +695,15 @@
`contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`
FROM `item`, `contact`
WHERE `item`.`uid` = %d
AND `item`.`contact-id` = %d
AND `item`.`visible` = 1 AND `item`.`deleted` = 0
AND `item`.`wall` = 1
AND `contact`.`id` = `item`.`contact-id`
AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
$sql_extra
AND `item`.`id`>%d
ORDER BY `item`.`received` DESC LIMIT %d ,%d ",
intval($user_info['uid']),
intval(local_user()),
intval($user_info['id']),
intval($since_id),
intval($start), intval($count)
);
@ -711,33 +728,41 @@
if (local_user()===false) return false;
$user_info = api_get_user($a);
// get last newtork messages
// in friendika starred item are private
// return favorites only for self
logger('api_favorites: self:' . $user_info['self']);
// params
$count = (x($_GET,'count')?$_GET['count']:20);
$page = (x($_REQUEST,'page')?$_REQUEST['page']-1:0);
if ($page<0) $page=0;
if ($user_info['self']==0) {
$ret = array();
} else {
// params
$count = (x($_GET,'count')?$_GET['count']:20);
$page = (x($_REQUEST,'page')?$_REQUEST['page']-1:0);
if ($page<0) $page=0;
$start = $page*$count;
$r = q("SELECT `item`.*, `item`.`id` AS `item_id`,
`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`,
`contact`.`network`, `contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`,
`contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`
FROM `item`, `contact`
WHERE `item`.`uid` = %d
AND `item`.`visible` = 1 AND `item`.`deleted` = 0
AND `item`.`starred` = 1
AND `contact`.`id` = `item`.`contact-id`
AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
$sql_extra
ORDER BY `item`.`received` DESC LIMIT %d ,%d ",
intval($user_info['uid']),
intval($start), intval($count)
);
$ret = api_format_items($r,$user_info);
$start = $page*$count;
$r = q("SELECT `item`.*, `item`.`id` AS `item_id`,
`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`,
`contact`.`network`, `contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`,
`contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`
FROM `item`, `contact`
WHERE `item`.`uid` = %d
AND `item`.`visible` = 1 AND `item`.`deleted` = 0
AND `item`.`starred` = 1
AND `contact`.`id` = `item`.`contact-id`
AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
$sql_extra
ORDER BY `item`.`received` DESC LIMIT %d ,%d ",
intval($user_info['uid']),
intval($start), intval($count)
);
$ret = api_format_items($r,$user_info);
}
$data = array('$statuses' => $ret);
switch($type){
@ -762,6 +787,7 @@
$ret = Array();
foreach($r as $item) {
localize_item($item);
$status_user = (($item['cid']==$user_info['id'])?$user_info: api_item_get_user($a,$item));
$status = array(
'created_at'=> api_date($item['created']),
@ -819,15 +845,21 @@
if (local_user()===false) return false;
$user_info = api_get_user($a);
// friends and followers only for self
if ($user_info['self']==0){
return false;
}
if (x($_GET,'cursor') && $_GET['cursor']=='undefined'){
/* this is to stop Hotot to load friends multiple times
* I'm not sure if I'm missing return something or
* is a bug in hotot. Workaround, meantime
*/
$ret=Array();
$data = array('$users' => $ret);
return api_apply_template("friends", $type, $data);
/*$ret=Array();
return array('$users' => $ret);*/
return false;
}
if($qtype == 'friends')
@ -845,15 +877,18 @@
}
$data = array('$users' => $ret);
return api_apply_template("friends", $type, $data);
return array('$users' => $ret);
}
function api_statuses_friends(&$a, $type){
return api_statuses_f($a,$type,"friends");
$data = api_statuses_f($a,$type,"friends");
if ($data===false) return false;
return api_apply_template("friends", $type, $data);
}
function api_statuses_followers(&$a, $type){
return api_statuses_f($a,$type,"followers");
$data = api_statuses_f($a,$type,"followers");
if ($data===false) return false;
return api_apply_template("friends", $type, $data);
}
api_register_func('api/statuses/friends','api_statuses_friends',true);
api_register_func('api/statuses/followers','api_statuses_followers',true);

View file

@ -16,7 +16,10 @@ function diaspora2bb($s) {
$s = preg_replace("/\*(.+?)\*/", '[i]$1[/i]', $s);
$s = preg_replace("/\_(.+?)\_/", '[i]$1[/i]', $s);
$s = str_replace(array('-^doublestar^-','-^doublescore-^','-^star^-','-^score^-'), array('**','__','*','_'), $s);
$s = preg_replace('/\!\[(.+?)\]\((.+?)\)/','[img]$2[/img]',$s);
$s = preg_replace('/\[(.+?)\]\((.+?)\)/','[url=$2]$1[/url]',$s);
$s = preg_replace('/\@\{(.+?)\; (.+?)\@(.+?)\}/','@[url=https://$3/u/$2]$1[/url]',$s);
$s = escape_tags($s);
return $s;
@ -40,6 +43,11 @@ function bb2diaspora($Text,$preserve_nl = false) {
$Text = str_replace("<", "&lt;", $Text);
$Text = str_replace(">", "&gt;", $Text);
// If we find any event code, turn it into an event.
// After we're finished processing the bbcode we'll
// replace all of the event code with a reformatted version.
$ev = bbtoevent($Text);
if($preserve_nl)
$Text = str_replace(array("\n","\r"), array('',''),$Text);
@ -54,8 +62,9 @@ function bb2diaspora($Text,$preserve_nl = false) {
// [img]pathtoimage[/img]
$Text = preg_replace("/\[url\]([$URLSearchString]*)\[\/url\]/", '[$1]($1)', $Text);
$Text = preg_replace("(\[url\=([$URLSearchString]*)\](.*?)\[/url\])", '[$2]($1)', $Text);
$Text = preg_replace("/\[url\]([$URLSearchString]*)\[\/url\]/ism", '[$1]($1)', $Text);
$Text = preg_replace("/\#\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '[#$2]($1)', $Text);
$Text = preg_replace("/\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '[$2]($1)', $Text);
// $Text = preg_replace("/\[img\](.*?)\[\/img\]/", t('Image/photo: ') . '$1', $Text);
// $Text = preg_replace("/\[img\](.*?)\[\/img\]/", t('image/photo'), $Text);
@ -156,19 +165,20 @@ function bb2diaspora($Text,$preserve_nl = false) {
// oembed tag
// $Text = oembed_bbcode2html($Text);
// $Text = oembed_bbcode2html($Text);
// If we found an event earlier, strip out all the event code and replace with a reformatted version.
// if(x($ev,'desc') && x($ev,'start')) {
// $sub = format_event_html($ev);
if(x($ev,'desc') && x($ev,'start')) {
// $Text = preg_replace("/\[event\-description\](.*?)\[\/event\-description\]/is",$sub,$Text);
//$Text = preg_replace("/\[event\-start\](.*?)\[\/event\-start\]/is",'',$Text);
// $Text = preg_replace("/\[event\-finish\](.*?)\[\/event\-finish\]/is",'',$Text);
// $Text = preg_replace("/\[event\-location\](.*?)\[\/event\-location\]/is",'',$Text);
// $Text = preg_replace("/\[event\-adjust\](.*?)\[\/event\-adjust\]/is",'',$Text);
// }
$sub = format_event_diaspora($ev);
$Text = preg_replace("/\[event\-description\](.*?)\[\/event\-description\]/is",$sub,$Text);
$Text = preg_replace("/\[event\-start\](.*?)\[\/event\-start\]/is",'',$Text);
$Text = preg_replace("/\[event\-finish\](.*?)\[\/event\-finish\]/is",'',$Text);
$Text = preg_replace("/\[event\-location\](.*?)\[\/event\-location\]/is",'',$Text);
$Text = preg_replace("/\[event\-adjust\](.*?)\[\/event\-adjust\]/is",'',$Text);
}
@ -176,3 +186,37 @@ function bb2diaspora($Text,$preserve_nl = false) {
return $Text;
}
function format_event_diaspora($ev) {
if(! ((is_array($ev)) && count($ev)))
return '';
$bd_format = t('l F d, Y \@ g:i A') ; // Friday January 18, 2011 @ 8 AM
$o = 'Friendika event notification:' . "\n";
$o .= '**' . bb2diaspora($ev['desc']) . '**' . "\n";
$o .= t('Starts:') . ' '
. (($ev['adjust']) ? day_translate(datetime_convert('UTC', 'UTC',
$ev['start'] , $bd_format ))
: day_translate(datetime_convert('UTC', 'UTC',
$ev['start'] , $bd_format)))
. "\n";
if(! $ev['nofinish'])
$o .= t('Finishes:') . ' '
. (($ev['adjust']) ? day_translate(datetime_convert('UTC', 'UTC',
$ev['finish'] , $bd_format ))
: day_translate(datetime_convert('UTC', 'UTC',
$ev['finish'] , $bd_format )))
. "\n";
if(strlen($ev['location']))
$o .= t('Location:') . bb2diaspora($ev['location'])
. "\n";
$o .= "\n";
return $o;
}

View file

@ -43,65 +43,65 @@ function bbcode($Text,$preserve_nl = false) {
$Text = preg_replace("/([^\]\=]|^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\.\=\_\~\#\%\$\!\+\,]+)/", '$1<a href="$2" target="external-link">$2</a>', $Text);
$Text = preg_replace("/\[url\]([$URLSearchString]*)\[\/url\]/", '<a href="$1" target="external-link">$1</a>', $Text);
$Text = preg_replace("(\[url\=([$URLSearchString]*)\](.*?)\[/url\])", '<a href="$1" target="external-link">$2</a>', $Text);
//$Text = preg_replace("(\[url\=([$URLSearchString]*)\]([$URLSearchString]*)\[/url\])", '<a href="$1" target="_blank">$2</a>', $Text);
$Text = preg_replace("/\[url\]([$URLSearchString]*)\[\/url\]/m", '<a href="$1" target="external-link">$1</a>', $Text);
$Text = preg_replace("/\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/m", '<a href="$1" target="external-link">$2</a>', $Text);
//$Text = preg_replace("/\[url\=([$URLSearchString]*)\]([$URLSearchString]*)\[\/url\]/m", '<a href="$1" target="_blank">$2</a>', $Text);
// Perform MAIL Search
$Text = preg_replace("(\[mail\]([$MAILSearchString]*)\[/mail\])", '<a href="mailto:$1">$1</a>', $Text);
$Text = preg_replace("/\[mail\]([$MAILSearchString]*)\[\/mail\]/", '<a href="mailto:$1">$1</a>', $Text);
$Text = preg_replace("/\[mail\=([$MAILSearchString]*)\](.*?)\[\/mail\]/", '<a href="mailto:$1">$2</a>', $Text);
// Check for bold text
$Text = preg_replace("(\[b\](.*?)\[\/b\])is",'<strong>$1</strong>',$Text);
$Text = preg_replace("(\[b\](.*?)\[\/b\])ism",'<strong>$1</strong>',$Text);
// Check for Italics text
$Text = preg_replace("(\[i\](.*?)\[\/i\])is",'<em>$1</em>',$Text);
$Text = preg_replace("(\[i\](.*?)\[\/i\])ism",'<em>$1</em>',$Text);
// Check for Underline text
$Text = preg_replace("(\[u\](.*?)\[\/u\])is",'<u>$1</u>',$Text);
$Text = preg_replace("(\[u\](.*?)\[\/u\])ism",'<u>$1</u>',$Text);
// Check for strike-through text
$Text = preg_replace("(\[s\](.*?)\[\/s\])is",'<strike>$1</strike>',$Text);
$Text = preg_replace("(\[s\](.*?)\[\/s\])ism",'<strike>$1</strike>',$Text);
// Check for over-line text
$Text = preg_replace("(\[o\](.*?)\[\/o\])is",'<span class="overline">$1</span>',$Text);
$Text = preg_replace("(\[o\](.*?)\[\/o\])ism",'<span class="overline">$1</span>',$Text);
// Check for colored text
$Text = preg_replace("(\[color=(.*?)\](.*?)\[\/color\])is","<span style=\"color: $1;\">$2</span>",$Text);
$Text = preg_replace("(\[color=(.*?)\](.*?)\[\/color\])ism","<span style=\"color: $1;\">$2</span>",$Text);
// Check for sized text
$Text = preg_replace("(\[size=(.*?)\](.*?)\[\/size\])is","<span style=\"font-size: $1;\">$2</span>",$Text);
$Text = preg_replace("(\[size=(.*?)\](.*?)\[\/size\])ism","<span style=\"font-size: $1;\">$2</span>",$Text);
// Check for list text
$Text = preg_replace("/\[list\](.*?)\[\/list\]/is", '<ul class="listbullet">$1</ul>' ,$Text);
$Text = preg_replace("/\[list=1\](.*?)\[\/list\]/is", '<ul class="listdecimal">$1</ul>' ,$Text);
$Text = preg_replace("/\[list=i\](.*?)\[\/list\]/s",'<ul class="listlowerroman">$1</ul>' ,$Text);
$Text = preg_replace("/\[list=I\](.*?)\[\/list\]/s", '<ul class="listupperroman">$1</ul>' ,$Text);
$Text = preg_replace("/\[list=a\](.*?)\[\/list\]/s", '<ul class="listloweralpha">$1</ul>' ,$Text);
$Text = preg_replace("/\[list=A\](.*?)\[\/list\]/s", '<ul class="listupperalpha">$1</ul>' ,$Text);
$Text = preg_replace("/\[li\](.*?)\[\/li\]/s", '<li>$1</li>' ,$Text);
$Text = preg_replace("/\[list\](.*?)\[\/list\]/ism", '<ul class="listbullet">$1</ul>' ,$Text);
$Text = preg_replace("/\[list=1\](.*?)\[\/list\]/ism", '<ul class="listdecimal">$1</ul>' ,$Text);
$Text = preg_replace("/\[list=i\](.*?)\[\/list\]/sm",'<ul class="listlowerroman">$1</ul>' ,$Text);
$Text = preg_replace("/\[list=I\](.*?)\[\/list\]/sm", '<ul class="listupperroman">$1</ul>' ,$Text);
$Text = preg_replace("/\[list=a\](.*?)\[\/list\]/sm", '<ul class="listloweralpha">$1</ul>' ,$Text);
$Text = preg_replace("/\[list=A\](.*?)\[\/list\]/sm", '<ul class="listupperalpha">$1</ul>' ,$Text);
$Text = preg_replace("/\[li\](.*?)\[\/li\]/sm", '<li>$1</li>' ,$Text);
$Text = preg_replace("/\[td\](.*?)\[\/td\]/s", '<td>$1</td>' ,$Text);
$Text = preg_replace("/\[tr\](.*?)\[\/tr\]/s", '<tr>$1</tr>' ,$Text);
$Text = preg_replace("/\[table\](.*?)\[\/table\]/s", '<table>$1</table>' ,$Text);
$Text = preg_replace("/\[td\](.*?)\[\/td\]/sm", '<td>$1</td>' ,$Text);
$Text = preg_replace("/\[tr\](.*?)\[\/tr\]/sm", '<tr>$1</tr>' ,$Text);
$Text = preg_replace("/\[table\](.*?)\[\/table\]/sm", '<table>$1</table>' ,$Text);
$Text = preg_replace("/\[table border=1\](.*?)\[\/table\]/s", '<table border="1" >$1</table>' ,$Text);
$Text = preg_replace("/\[table border=0\](.*?)\[\/table\]/s", '<table border="0" >$1</table>' ,$Text);
$Text = preg_replace("/\[table border=1\](.*?)\[\/table\]/sm", '<table border="1" >$1</table>' ,$Text);
$Text = preg_replace("/\[table border=0\](.*?)\[\/table\]/sm", '<table border="0" >$1</table>' ,$Text);
// $Text = str_replace("[*]", "<li>", $Text);
// Check for font change text
$Text = preg_replace("(\[font=(.*?)\](.*?)\[\/font\])","<span style=\"font-family: $1;\">$2</span>",$Text);
$Text = preg_replace("/\[font=(.*?)\](.*?)\[\/font\]/m","<span style=\"font-family: $1;\">$2</span>",$Text);
// Declare the format for [code] layout
$Text = preg_replace_callback("/\[code\](.*?)\[\/code\]/is",'stripcode_br_cb',$Text);
$Text = preg_replace_callback("/\[code\](.*?)\[\/code\]/ism",'stripcode_br_cb',$Text);
$CodeLayout = '<code>$1</code>';
// Check for [code] text
$Text = preg_replace("/\[code\](.*?)\[\/code\]/is","$CodeLayout", $Text);
$Text = preg_replace("/\[code\](.*?)\[\/code\]/ism","$CodeLayout", $Text);
@ -109,22 +109,22 @@ function bbcode($Text,$preserve_nl = false) {
// Declare the format for [quote] layout
$QuoteLayout = '<blockquote>$1</blockquote>';
// Check for [quote] text
$Text = preg_replace("/\[quote\](.*?)\[\/quote\]/is","$QuoteLayout", $Text);
$Text = preg_replace("/\[quote\](.*?)\[\/quote\]/ism","$QuoteLayout", $Text);
// Images
// [img]pathtoimage[/img]
$Text = preg_replace("/\[img\](.*?)\[\/img\]/", '<img src="$1" alt="' . t('Image/photo') . '" />', $Text);
$Text = preg_replace("/\[img\](.*?)\[\/img\]/ism", '<img src="$1" alt="' . t('Image/photo') . '" />', $Text);
// html5 video and audio
$Text = preg_replace("/\[video\](.*?)\[\/video\]/", '<video src="$1" controls="controls" width="425" height="350"><a href="$1">$1</a></video>', $Text);
$Text = preg_replace("/\[video\](.*?)\[\/video\]/ism", '<video src="$1" controls="controls" width="425" height="350"><a href="$1">$1</a></video>', $Text);
$Text = preg_replace("/\[audio\](.*?)\[\/audio\]/", '<audio src="$1" controls="controls"><a href="$1">$1</a></audio>', $Text);
$Text = preg_replace("/\[audio\](.*?)\[\/audio\]/ism", '<audio src="$1" controls="controls"><a href="$1">$1</a></audio>', $Text);
$Text = preg_replace("/\[iframe\](.*?)\[\/iframe\]/", '<iframe src="$1" width="425" height="350"><a href="$1">$1</a></iframe>', $Text);
$Text = preg_replace("/\[iframe\](.*?)\[\/iframe\]/ism", '<iframe src="$1" width="425" height="350"><a href="$1">$1</a></iframe>', $Text);
// [img=widthxheight]image source[/img]
$Text = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/", '<img src="$3" style="height:{$2}px; width:{$1}px;" >', $Text);
$Text = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '<img src="$3" style="height:{$2}px; width:{$1}px;" >', $Text);
if (get_pconfig(local_user(), 'oembed', 'use_for_youtube' )==1){
// use oembed for youtube links
@ -132,13 +132,15 @@ function bbcode($Text,$preserve_nl = false) {
$Text = preg_replace("/\[\/youtube\]/",'[/embed]',$Text);
} else {
// Youtube extensions
$Text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/watch\?v\=(.*?)\[\/youtube\]/",'[youtube]$1[/youtube]',$Text);
$Text = preg_replace("/\[youtube\]https?:\/\/youtu.be\/(.*?)\[\/youtube\]/",'[youtube]$1[/youtube]',$Text);
$Text = preg_replace("/\[youtube\](.*?)\[\/youtube\]/", '<iframe width="425" height="349" src="http://www.youtube.com/embed/$1" frameborder="0" ></iframe>', $Text);
$Text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/watch\?v\=(.*?)\[\/youtube\]/ism",'[youtube]$1[/youtube]',$Text);
$Text = preg_replace("/\[youtube\]https?:\/\/www.youtube.com\/embed\/(.*?)\[\/youtube\]/ism",'[youtube]$1[/youtube]',$Text);
$Text = preg_replace("/\[youtube\]https?:\/\/youtu.be\/(.*?)\[\/youtube\]/ism",'[youtube]$1[/youtube]',$Text);
$Text = preg_replace("/\[youtube\]([A-Za-z0-9\-_=]+)(.*?)\[\/youtube\]/ism", '<iframe width="425" height="350" src="http://www.youtube.com/embed/$1" frameborder="0" ></iframe>', $Text);
}
// $Text = preg_replace("/\[youtube\](.*?)\[\/youtube\]/", '<object width="425" height="350" type="application/x-shockwave-flash" data="http://www.youtube.com/v/$1" ><param name="movie" value="http://www.youtube.com/v/$1"></param><!--[if IE]><embed src="http://www.youtube.com/v/$1" type="application/x-shockwave-flash" width="425" height="350" /><![endif]--></object>', $Text);
// $Text = preg_replace("/\[youtube\](.*?)\[\/youtube\]/", '<object width="425" height="350" type="application/x-shockwave-flash" data="http://www.youtube.com/v/$1" ><param name="movie" value="http://www.youtube.com/v/$1"></param><!--[if IE]><embed src="http://www.youtube.com/v/$1" type="application/x-shockwave-flash" width="425" height="350" /><![endif]--></object>', $Text);
// oembed tag
$Text = oembed_bbcode2html($Text);
@ -148,11 +150,11 @@ function bbcode($Text,$preserve_nl = false) {
if(x($ev,'desc') && x($ev,'start')) {
$sub = format_event_html($ev);
$Text = preg_replace("/\[event\-description\](.*?)\[\/event\-description\]/is",$sub,$Text);
$Text = preg_replace("/\[event\-start\](.*?)\[\/event\-start\]/is",'',$Text);
$Text = preg_replace("/\[event\-finish\](.*?)\[\/event\-finish\]/is",'',$Text);
$Text = preg_replace("/\[event\-location\](.*?)\[\/event\-location\]/is",'',$Text);
$Text = preg_replace("/\[event\-adjust\](.*?)\[\/event\-adjust\]/is",'',$Text);
$Text = preg_replace("/\[event\-description\](.*?)\[\/event\-description\]/ism",$sub,$Text);
$Text = preg_replace("/\[event\-start\](.*?)\[\/event\-start\]/ism",'',$Text);
$Text = preg_replace("/\[event\-finish\](.*?)\[\/event\-finish\]/ism",'',$Text);
$Text = preg_replace("/\[event\-location\](.*?)\[\/event\-location\]/ism",'',$Text);
$Text = preg_replace("/\[event\-adjust\](.*?)\[\/event\-adjust\]/ism",'',$Text);
}

View file

@ -80,6 +80,7 @@ function localize_item(&$item){
}
}
/**

View file

@ -225,3 +225,71 @@ function pkcs5_unpad($text)
if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) return false;
return substr($text, 0, -1 * $pad);
}
function AES256CBC_encrypt($data,$key,$iv) {
return mcrypt_encrypt(
MCRYPT_RIJNDAEL_128,
str_pad($key,32,"\0"),
pkcs5_pad($data,16),
MCRYPT_MODE_CBC,
str_pad($iv,16,"\0"));
}
function AES256CBC_decrypt($data,$key,$iv) {
return pkcs5_unpad(mcrypt_decrypt(
MCRYPT_RIJNDAEL_128,
str_pad($key,32,"\0"),
$data,
MCRYPT_MODE_CBC,
str_pad($iv,16,"\0")));
}
function aes_encapsulate($data,$pubkey) {
$key = random_string(32,RANDOM_STRING_TEXT);
$iv = random_string(16,RANDOM_STRING_TEXT);
$result['data'] = base64url_encode(AES256CBC_encrypt($data,$key,$iv),true);
openssl_public_encrypt($key,$k,$pubkey);
$result['key'] = base64url_encode($k,true);
openssl_public_encrypt($iv,$i,$pubkey);
$result['iv'] = base64url_encode($i,true);
return $result;
}
function aes_unencapsulate($data,$prvkey) {
openssl_private_decrypt(base64url_decode($data['key']),$k,$prvkey);
openssl_private_decrypt(base64url_decode($data['iv']),$i,$prvkey);
return AES256CBC_decrypt(base64url_decode($data['data']),$k,$i);
}
// This has been superceded.
function zot_encapsulate($data,$envelope,$pubkey) {
$res = aes_encapsulate($data,$pubkey);
return <<< EOT
<?xml version='1.0' encoding='UTF-8'?>
<zot:msg xmlns:zot='http://purl.org/zot/1.0'>
<zot:key>{$res['key']}</zot:key>
<zot:iv>{$res['iv']}</zot:iv>
<zot:env>$s1</zot:env>
<zot:sig key_id="$keyid">$sig</zot:sig>
<zot:alg>AES-256-CBC</zot:alg>
<zot:data type='application/magic-envelope+xml'>{$res['data']}</zot:data>
</zot:msg>
EOT;
}
// so has this
function zot_unencapsulate($data,$prvkey) {
$ret = array();
$c = array();
$x = parse_xml_string($data);
$c = array('key' => $x->key,'iv' => $x->iv,'data' => $x->data);
openssl_private_decrypt(base64url_decode($x->sender),$s,$prvkey);
$ret['sender'] = $s;
$ret['data'] = aes_unencapsulate($x,$prvkey);
return $ret;
}

447
include/delivery.php Normal file
View file

@ -0,0 +1,447 @@
<?php
require_once("boot.php");
function delivery_run($argv, $argc){
global $a, $db;
if(is_null($a)){
$a = new App;
}
if(is_null($db)) {
@include(".htconfig.php");
require_once("dba.php");
$db = new dba($db_host, $db_user, $db_pass, $db_data);
unset($db_host, $db_user, $db_pass, $db_data);
}
require_once("session.php");
require_once("datetime.php");
require_once('include/items.php');
require_once('include/bbcode.php');
require_once('include/diaspora.php');
load_config('config');
load_config('system');
load_hooks();
if($argc < 3)
return;
$a->set_baseurl(get_config('system','url'));
logger('delivery: invoked: ' . print_r($argv,true));
$cmd = $argv[1];
$item_id = intval($argv[2]);
$contact_id = intval($argv[3]);
// Some other process may have delivered this item already.
$r = q("select * from deliverq where cmd = '%s' and item = %d and contact = %d limit 1",
dbesc($cmd),
dbesc($item_id),
dbesc($contact_id)
);
if(! count($r)) {
return;
}
// It's ours to deliver. Remove it from the queue.
q("delete from deliverq where cmd = '%s' and item = %d and contact = %d limit 1",
dbesc($cmd),
dbesc($item_id),
dbesc($contact_id)
);
if((! $item_id) || (! $contact_id))
return;
$expire = false;
$top_level = false;
$recipients = array();
$url_recipients = array();
$normal_mode = true;
$recipients[] = $contact_id;
if($cmd === 'expire') {
$normal_mode = false;
$expire = true;
$items = q("SELECT * FROM `item` WHERE `uid` = %d AND `wall` = 1
AND `deleted` = 1 AND `changed` > UTC_TIMESTAMP - INTERVAL 30 MINUTE",
intval($item_id)
);
$uid = $item_id;
$item_id = 0;
if(! count($items))
return;
}
else {
// find ancestors
$r = q("SELECT * FROM `item` WHERE `id` = %d LIMIT 1",
intval($item_id)
);
if((! count($r)) || (! intval($r[0]['parent']))) {
return;
}
$target_item = $r[0];
$parent_id = intval($r[0]['parent']);
$uid = $r[0]['uid'];
$updated = $r[0]['edited'];
$items = q("SELECT `item`.*, `sign`.`signed_text`,`sign`.`signature`,`sign`.`signer`
FROM `item` LEFT JOIN `sign` ON `sign`.`iid` = `item`.`id` WHERE `parent` = %d ORDER BY `id` ASC",
intval($parent_id)
);
if(! count($items)) {
return;
}
$icontacts = q("SELECT * FROM `contact` WHERE `id` IN ( SELECT distinct(`contact-id`) FROM `item` where `parent` = %d ) ",
intval($parent_id)
);
if(! count($icontacts))
return;
// avoid race condition with deleting entries
if($items[0]['deleted']) {
foreach($items as $item)
$item['deleted'] = 1;
}
if((count($items) == 1) && ($items[0]['uri'] === $items[0]['parent-uri'])) {
logger('delivery: top level post');
$top_level = true;
}
}
$r = q("SELECT `contact`.*, `user`.`pubkey` AS `upubkey`, `user`.`prvkey` AS `uprvkey`,
`user`.`timezone`, `user`.`nickname`, `user`.`sprvkey`, `user`.`spubkey`,
`user`.`page-flags`, `user`.`prvnets`
FROM `contact` LEFT JOIN `user` ON `user`.`uid` = `contact`.`uid`
WHERE `contact`.`uid` = %d AND `contact`.`self` = 1 LIMIT 1",
intval($uid)
);
if(! count($r))
return;
$owner = $r[0];
$walltowall = ((($top_level) && ($owner['id'] != $items[0]['contact-id'])) ? true : false);
$public_message = true;
// fill this in with a single salmon slap if applicable
$slap = '';
require_once('include/group.php');
$parent = $items[0];
// This is IMPORTANT!!!!
// We will only send a "notify owner to relay" or followup message if the referenced post
// originated on our system by virtue of having our hostname somewhere
// in the URI, AND it was a comment (not top_level) AND the parent originated elsewhere.
// if $parent['wall'] == 1 we will already have the parent message in our array
// and we will relay the whole lot.
// expire sends an entire group of expire messages and cannot be forwarded.
// However the conversation owner will be a part of the conversation and will
// be notified during this run.
// Other DFRN conversation members will be alerted during polled updates.
// Diaspora members currently are not notified of expirations, and other networks have
// either limited or no ability to process deletions. We should at least fix Diaspora
// by stringing togther an array of retractions and sending them onward.
$localhost = $a->get_hostname();
if(strpos($localhost,':'))
$localhost = substr($localhost,0,strpos($localhost,':'));
/**
*
* Be VERY CAREFUL if you make any changes to the following line. Seemingly innocuous changes
* have been known to cause runaway conditions which affected several servers, along with
* permissions issues.
*
*/
if((! $top_level) && ($parent['wall'] == 0) && (! $expire) && (stristr($target_item['uri'],$localhost))) {
logger('relay denied for delivery agent.');
/* no relay allowed for direct contact delivery */
return;
}
if((strlen($parent['allow_cid']))
|| (strlen($parent['allow_gid']))
|| (strlen($parent['deny_cid']))
|| (strlen($parent['deny_gid']))) {
$public_message = false; // private recipients, not public
}
$conversant_str = intval($contact_id);
$r = q("SELECT * FROM `contact` WHERE `id` = %d AND `blocked` = 0 AND `pending` = 0",
intval($contact_id)
);
if(count($r))
$contact = $r[0];
$feed_template = get_markup_template('atom_feed.tpl');
$mail_template = get_markup_template('atom_mail.tpl');
$atom = '';
$slaps = array();
$hubxml = feed_hublinks();
$birthday = feed_birthday($owner['uid'],$owner['timezone']);
if(strlen($birthday))
$birthday = '<dfrn:birthday>' . xmlify($birthday) . '</dfrn:birthday>';
$atom .= replace_macros($feed_template, array(
'$version' => xmlify(FRIENDIKA_VERSION),
'$feed_id' => xmlify($a->get_baseurl() . '/profile/' . $owner['nickname'] ),
'$feed_title' => xmlify($owner['name']),
'$feed_updated' => xmlify(datetime_convert('UTC', 'UTC', $updated . '+00:00' , ATOM_TIME)) ,
'$hub' => $hubxml,
'$salmon' => '', // private feed, we don't use salmon here
'$name' => xmlify($owner['name']),
'$profile_page' => xmlify($owner['url']),
'$photo' => xmlify($owner['photo']),
'$thumb' => xmlify($owner['thumb']),
'$picdate' => xmlify(datetime_convert('UTC','UTC',$owner['avatar-date'] . '+00:00' , ATOM_TIME)) ,
'$uridate' => xmlify(datetime_convert('UTC','UTC',$owner['uri-date'] . '+00:00' , ATOM_TIME)) ,
'$namdate' => xmlify(datetime_convert('UTC','UTC',$owner['name-date'] . '+00:00' , ATOM_TIME)) ,
'$birthday' => $birthday
));
foreach($items as $item) {
if(! $item['parent'])
continue;
// private emails may be in included in public conversations. Filter them.
if(($public_message) && $item['private'])
continue;
$item_contact = get_item_contact($item,$icontacts);
if(! $item_contact)
continue;
$atom .= atom_entry($item,'text',$item_contact,$owner,true);
if(($top_level) && ($public_message) && ($item['author-link'] === $item['owner-link']) && (! $expire))
$slaps[] = atom_entry($item,'html',$item_contact,$owner,true);
}
$atom .= '</feed>' . "\r\n";
logger('notifier: ' . $atom, LOGGER_DATA);
logger('notifier: slaps: ' . print_r($slaps,true), LOGGER_DATA);
require_once('include/salmon.php');
if($contact['self'])
return;
$deliver_status = 0;
switch($contact['network']) {
case NETWORK_DFRN :
logger('notifier: dfrndelivery: ' . $contact['name']);
$deliver_status = dfrn_deliver($owner,$contact,$atom);
logger('notifier: dfrn_delivery returns ' . $deliver_status);
if($deliver_status == (-1)) {
logger('notifier: delivery failed: queuing message');
// queue message for redelivery
q("INSERT INTO `queue` ( `cid`, `created`, `last`, `content`)
VALUES ( %d, '%s', '%s', '%s') ",
intval($contact['id']),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
dbesc($atom)
);
}
break;
case NETWORK_OSTATUS :
// Do not send to otatus if we are not configured to send to public networks
if($owner['prvnets'])
break;
if(get_config('system','ostatus_disabled') || get_config('system','dfrn_only'))
break;
// only send salmon if public - e.g. if it's ok to notify
// a public hub, it's ok to send a salmon
if((count($slaps)) && ($public_message) && (! $expire)) {
logger('notifier: slapdelivery: ' . $contact['name']);
foreach($slaps as $slappy) {
if($contact['notify']) {
$deliver_status = slapper($owner,$contact['notify'],$slappy);
if($deliver_status == (-1)) {
// queue message for redelivery
q("INSERT INTO `queue` ( `cid`, `created`, `last`, `content`)
VALUES ( %d, '%s', '%s', '%s') ",
intval($contact['id']),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
dbesc($slappy)
);
}
}
}
}
break;
case NETWORK_MAIL :
if(get_config('system','dfrn_only'))
break;
// WARNING: does not currently convert to RFC2047 header encodings, etc.
$addr = $contact['addr'];
if(! strlen($addr))
break;
if($cmd === 'wall-new' || $cmd === 'comment-new') {
$it = null;
if($cmd === 'wall-new')
$it = $items[0];
else {
$r = q("SELECT * FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1",
intval($argv[2]),
intval($uid)
);
if(count($r))
$it = $r[0];
}
if(! $it)
break;
$local_user = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1",
intval($uid)
);
if(! count($local_user))
break;
$reply_to = '';
$r1 = q("SELECT * FROM `mailacct` WHERE `uid` = %d LIMIT 1",
intval($uid)
);
if($r1 && $r1[0]['reply_to'])
$reply_to = $r1[0]['reply_to'];
$subject = (($it['title']) ? $it['title'] : t("\x28no subject\x29")) ;
$headers = 'From: ' . $local_user[0]['username'] . ' <' . $local_user[0]['email'] . '>' . "\n";
if($reply_to)
$headers .= 'Reply-to: ' . $reply_to . "\n";
$headers .= 'Message-id: <' . $it['uri'] . '>' . "\n";
if($it['uri'] !== $it['parent-uri']) {
$header .= 'References: <' . $it['parent-uri'] . '>' . "\n";
if(! strlen($it['title'])) {
$r = q("SELECT `title` FROM `item` WHERE `parent-uri` = '%s' LIMIT 1",
dbesc($it['parent-uri'])
);
if(count($r)) {
$subtitle = $r[0]['title'];
if($subtitle) {
if(strncasecmp($subtitle,'RE:',3))
$subject = $subtitle;
else
$subject = 'Re: ' . $subtitle;
}
}
}
}
$headers .= 'MIME-Version: 1.0' . "\n";
$headers .= 'Content-Type: text/html; charset=UTF-8' . "\n";
$headers .= 'Content-Transfer-Encoding: 8bit' . "\n\n";
$html = prepare_body($it);
$message = '<html><body>' . $html . '</body></html>';
logger('notifier: email delivery to ' . $addr);
mail($addr, $subject, $message, $headers);
}
break;
case NETWORK_DIASPORA :
logger('delivery: diaspora deliver: ' . $contact['name']);
if(get_config('system','dfrn_only') || (! get_config('system','diaspora_enabled')) || (! $normal_mode))
break;
if(! $contact['pubkey'])
break;
if($target_item['verb'] === ACTIVITY_DISLIKE) {
// unsupported
break;
}
elseif(($target_item['deleted']) && ($target_item['verb'] !== ACTIVITY_LIKE)) {
logger('delivery: diaspora retract: ' . $contact['name']);
// diaspora delete,
diaspora_send_retraction($target_item,$owner,$contact);
break;
}
elseif($target_item['parent'] != $target_item['id']) {
logger('delivery: diaspora relay: ' . $contact['name']);
// we are the relay - send comments, likes and unlikes to our conversants
diaspora_send_relay($target_item,$owner,$contact);
break;
}
elseif(($top_level) && (! $walltowall)) {
// currently no workable solution for sending walltowall
logger('delivery: diaspora status: ' . $contact['name']);
diaspora_send_status($target_item,$owner,$contact);
break;
}
logger('delivery: diaspora unknown mode: ' . $contact['name']);
break;
case NETWORK_FEED :
case NETWORK_FACEBOOK :
if(get_config('system','dfrn_only'))
break;
default:
break;
}
return;
}
if (array_search(__file__,get_included_files())===0){
delivery_run($argv,$argc);
killme();
}

View file

@ -3,6 +3,7 @@
require_once('include/crypto.php');
require_once('include/items.php');
require_once('include/bb2diaspora.php');
require_once('include/contact_selectors.php');
function diaspora_dispatch($importer,$msg) {
@ -139,10 +140,9 @@ EOT;
$encrypted_outer_key_bundle = '';
openssl_public_encrypt($outer_json,$encrypted_outer_key_bundle,$pubkey);
logger('outer_bundle_encrypt: ' . openssl_error_string());
$b64_encrypted_outer_key_bundle = base64_encode($encrypted_outer_key_bundle);
logger('outer_bundle: ' . $b64_encrypted_outer_key_bundle . ' key: ' . $pubkey);
logger('outer_bundle: ' . $b64_encrypted_outer_key_bundle . ' key: ' . $pubkey, LOGGER_DATA);
$encrypted_header_json_object = json_encode(array('aes_key' => base64_encode($encrypted_outer_key_bundle),
'ciphertext' => base64_encode($ciphertext)));
@ -222,7 +222,7 @@ function diaspora_decode($importer,$xml) {
* </decrypted_header>
*/
logger('decrypted: ' . $decrypted);
logger('decrypted: ' . $decrypted, LOGGER_DEBUG);
$idom = parse_xml_string($decrypted,false);
$inner_iv = base64_decode($idom->iv);
@ -398,6 +398,7 @@ function diaspora_request($importer,$xml) {
function diaspora_post($importer,$xml) {
$a = get_app();
$guid = notags(unxmlify($xml->guid));
$diaspora_handle = notags(unxmlify($xml->diaspora_handle));
@ -417,8 +418,10 @@ function diaspora_post($importer,$xml) {
dbesc($message_id),
dbesc($guid)
);
if(count($r))
if(count($r)) {
logger('diaspora_post: message exists: ' . $guid);
return;
}
// allocate a guid on our system - we aren't fixing any collisions.
// we're ignoring them
@ -453,8 +456,16 @@ function diaspora_post($importer,$xml) {
$datarray['author-link'] = $contact['url'];
$datarray['author-avatar'] = $contact['thumb'];
$datarray['body'] = $body;
$datarray['app'] = 'Diaspora';
item_store($datarray);
$message_id = item_store($datarray);
if($message_id) {
q("update item set plink = '%s' where id = %d limit 1",
dbesc($a->get_baseurl() . '/display/' . $importer['nickname'] . '/' . $message_id),
intval($message_id)
);
}
return;
@ -462,6 +473,7 @@ function diaspora_post($importer,$xml) {
function diaspora_comment($importer,$xml,$msg) {
$a = get_app();
$guid = notags(unxmlify($xml->guid));
$parent_guid = notags(unxmlify($xml->parent_guid));
$diaspora_handle = notags(unxmlify($xml->diaspora_handle));
@ -474,8 +486,10 @@ function diaspora_comment($importer,$xml,$msg) {
$text = $xml->text;
$contact = diaspora_get_contact_by_handle($importer['uid'],$msg['author']);
if(! $contact)
if(! $contact) {
logger('diaspora_comment: cannot find contact: ' . $msg['author']);
return;
}
if(($contact['rel'] == CONTACT_IS_FOLLOWER) || ($contact['blocked']) || ($contact['readonly'])) {
logger('diaspora_comment: Ignoring this author.');
@ -483,6 +497,15 @@ function diaspora_comment($importer,$xml,$msg) {
// NOTREACHED
}
$r = q("SELECT * FROM `item` WHERE `uid` = %d AND `guid` = '%s' LIMIT 1",
intval($importer['uid']),
dbesc($guid)
);
if(count($r)) {
logger('diaspora_comment: our comment just got relayed back to us (or there was a guid collision) : ' . $guid);
return;
}
$r = q("SELECT * FROM `item` WHERE `uid` = %d AND `guid` = '%s' LIMIT 1",
intval($importer['uid']),
dbesc($parent_guid)
@ -558,9 +581,17 @@ function diaspora_comment($importer,$xml,$msg) {
$datarray['author-link'] = $person['url'];
$datarray['author-avatar'] = ((x($person,'thumb')) ? $person['thumb'] : $person['photo']);
$datarray['body'] = $body;
$datarray['app'] = 'Diaspora';
$message_id = item_store($datarray);
if($message_id) {
q("update item set plink = '%s' where id = %d limit 1",
dbesc($a->get_baseurl() . '/display/' . $importer['nickname'] . '/' . $message_id),
intval($message_id)
);
}
if(! $parent_author_signature) {
q("insert into sign (`iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ",
intval($message_id),
@ -580,6 +611,7 @@ function diaspora_comment($importer,$xml,$msg) {
function diaspora_photo($importer,$xml,$msg) {
$a = get_app();
$remote_photo_path = notags(unxmlify($xml->remote_photo_path));
$remote_photo_name = notags(unxmlify($xml->remote_photo_name));
@ -647,8 +679,10 @@ function diaspora_like($importer,$xml,$msg) {
return;
$contact = diaspora_get_contact_by_handle($importer['uid'],$msg['author']);
if(! $contact)
if(! $contact) {
logger('diaspora_like: cannot find contact: ' . $msg['author']);
return;
}
if(($contact['rel'] == CONTACT_IS_FOLLOWER) || ($contact['blocked']) || ($contact['readonly'])) {
logger('diaspora_like: Ignoring this author.');
@ -715,8 +749,8 @@ function diaspora_like($importer,$xml,$msg) {
}
if($parent_author_signature) {
// $owner_signed_data = $guid . ';' . $parent_guid . ';' . $target_type . ';' . $positive . ';' . $msg['author'];
$owner_signed_data = $guid . ';' . $parent_guid . ';' . $target_type . ';' . $positive . ';' . $diaspora_handle;
$owner_signed_data = $guid . ';' . $target_type . ';' . $parent_guid . ';' . $positive . ';' . $diaspora_handle;
$parent_author_signature = base64_decode($parent_author_signature);
@ -776,6 +810,8 @@ EOT;
$plink = '[url=' . $a->get_baseurl() . '/display/' . $importer['nickname'] . '/' . $parent_item['id'] . ']' . $post_type . '[/url]';
$arr['body'] = sprintf( $bodyverb, $ulink, $alink, $plink );
$arr['app'] = 'Diaspora';
$arr['private'] = $parent_item['private'];
$arr['verb'] = $activity;
$arr['object-type'] = $objtype;
@ -786,6 +822,14 @@ EOT;
$message_id = item_store($arr);
if($message_id) {
q("update item set plink = '%s' where id = %d limit 1",
dbesc($a->get_baseurl() . '/display/' . $importer['nickname'] . '/' . $message_id),
intval($message_id)
);
}
if(! $parent_author_signature) {
q("insert into sign (`iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ",
intval($message_id),
@ -897,11 +941,12 @@ function diaspora_send_status($item,$owner,$contact) {
}
}
$body = xmlify(bb2diaspora($body));
$body = xmlify(html_entity_decode(bb2diaspora($body)));
$public = (($item['private']) ? 'false' : 'true');
require_once('include/datetime.php');
$created = datetime_convert('UTC','UTC',$item['created'],'Y-m-d h:i:s \U\T\C');
$created = datetime_convert('UTC','UTC',$item['created'],'Y-m-d H:i:s \U\T\C');
$tpl = get_markup_template('diaspora_post.tpl');
$msg = replace_macros($tpl, array(
@ -953,7 +998,7 @@ function diaspora_send_images($item,$owner,$contact,$images) {
'$guid' => xmlify($r[0]['guid']),
'$handle' => xmlify($image['handle']),
'$public' => xmlify($public),
'$created_at' => xmlify(datetime_convert('UTC','UTC',$r[0]['created'],'Y-m-d h:i:s \U\T\C'))
'$created_at' => xmlify(datetime_convert('UTC','UTC',$r[0]['created'],'Y-m-d H:i:s \U\T\C'))
));
@ -990,7 +1035,7 @@ function diaspora_send_followup($item,$owner,$contact) {
$like = false;
}
$text = bb2diaspora($item['body']);
$text = html_entity_decode(bb2diaspora($item['body']));
// sign it
@ -1035,14 +1080,6 @@ function diaspora_send_relay($item,$owner,$contact) {
else
return;
// fetch the original signature
$r = q("select * from sign where iid = %d limit 1",
intval($item['id'])
);
if(! count($r))
return;
$orig_sign = $r[0];
if($item['verb'] === ACTIVITY_LIKE) {
$tpl = get_markup_template('diaspora_like_relay.tpl');
$like = true;
@ -1054,15 +1091,60 @@ function diaspora_send_relay($item,$owner,$contact) {
$like = false;
}
$text = bb2diaspora($item['body']);
$body = $item['body'];
$text = html_entity_decode(bb2diaspora($body));
// fetch the original signature if somebody sent the post to us to relay
// If we are relaying for a reply originating on our own account, there wasn't a 'send to relay'
// action. It wasn't needed. In that case create the original signature and the
// owner (parent author) signature
// comments from other networks will be relayed under our name, with a brief
// preamble to describe what's happening and noting the real author
$r = q("select * from sign where iid = %d limit 1",
intval($item['id'])
);
if(count($r)) {
$orig_sign = $r[0];
$signed_text = $orig_sign['signed_text'];
$authorsig = $orig_sign['signature'];
$handle = $orig_sign['signer'];
}
else {
$itemcontact = q("select * from contact where `id` = %d limit 1",
intval($item['contact-id'])
);
if(count($itemcontact)) {
if(! $itemcontact[0]['self']) {
$prefix = sprintf( t('[Relayed] Comment authored by %s from network %s'),
'['. $item['author-name'] . ']' . '(' . $item['author-link'] . ')',
network_to_name($itemcontact['network'])) . "\n";
$body = $prefix . $body;
}
}
else {
if($like)
$signed_text = $item['guid'] . ';' . $target_type . ';' . $parent_guid . ';' . $positive . ';' . $myaddr;
else
$signed_text = $item['guid'] . ';' . $parent_guid . ';' . $text . ';' . $myaddr;
$authorsig = base64_encode(rsa_sign($signed_text,$owner['uprvkey'],'sha'));
q("insert into sign (`iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ",
intval($item['id']),
dbesc($signed_text),
dbesc(base64_encode($authorsig)),
dbesc($myaddr)
);
$handle = $myaddr;
}
}
// sign it
if($like)
$parent_signed_text = $orig_sign['signed_text'];
else
$parent_signed_text = $orig_sign['signed_text'];
$parentauthorsig = base64_encode(rsa_sign($signed_text,$owner['uprvkey'],'sha'));
$msg = replace_macros($tpl,array(
@ -1071,18 +1153,11 @@ function diaspora_send_relay($item,$owner,$contact) {
'$target_type' =>xmlify($target_type),
'$authorsig' => xmlify($orig_sign['signature']),
'$parentsig' => xmlify($parentauthorsig),
'$text' => xmlify($text),
'$body' => xmlify($text),
'$positive' => xmlify($positive),
'$diaspora_handle' => xmlify($myaddr)
'$handle' => xmlify($handle)
));
// fetch the original signature
$r = q("select * from sign where iid = %d limit 1",
intval($item['id'])
);
if(! count($r))
return;
logger('diaspora_relay_comment: base message: ' . $msg, LOGGER_DATA);
$slap = 'xml=' . urlencode(urlencode(diaspora_msg_build($msg,$owner,$contact,$owner['uprvkey'],$contact['pubkey'])));

View file

@ -154,7 +154,7 @@ $o .= <<< EOT
<div id="sidebar-group-list">
<ul id="sidebar-group-ul">
<li class="sidebar-group-li" ><a href="$every" $selected >$linktext</a></li>
<li class="sidebar-group-li" ><a href="$every" class="sidebar-group-element" $selected >$linktext</a></li>
EOT;
@ -170,10 +170,10 @@ EOT;
$selected = (($group_id == $rr['id']) ? ' class="group-selected" ' : '');
$o .= ' <li class="sidebar-group-li">'
. (($edit) ? "<a href=\"group/{$rr['id']}\" title=\"" . t('Edit')
. "\" ><img src=\"images/spencil.gif\" alt=\"" . t('Edit') . "\"></a> " : "")
. "\" class=\"groupsideedit\" ><img src=\"images/spencil.gif\" alt=\"" . t('Edit') . "\"></a> " : "")
. (($cid) ? '<input type="checkbox" class="' . (($selected) ? 'ticked' : 'unticked') . '" onclick="contactgroupChangeMember(' . $rr['id'] . ',' . $cid . ');return true;" '
. ((in_array($rr['id'],$member_of)) ? ' checked="checked" ' : '') . '/>' : '')
. "<a href=\"$each/{$rr['id']}\" $selected >{$rr['name']}</a></li>\r\n";
. "<a href=\"$each/{$rr['id']}\" class=\"sidebar-group-element\" $selected >{$rr['name']}</a></li>\r\n";
}
}
$o .= " </ul>\r\n </div>";

View file

@ -20,6 +20,8 @@ function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0)
for($x = 2; $x < $a->argc; $x++) {
if($a->argv[$x] == 'converse')
$converse = true;
if($a->argv[$x] == 'starred')
$starred = true;
}
}
@ -112,8 +114,10 @@ function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0)
`contact`.`name`, `contact`.`photo`, `contact`.`url`,
`contact`.`name-date`, `contact`.`uri-date`, `contact`.`avatar-date`,
`contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`,
`contact`.`id` AS `contact-id`, `contact`.`uid` AS `contact-uid`
`contact`.`id` AS `contact-id`, `contact`.`uid` AS `contact-uid`,
`sign`.`signed_text`, `sign`.`signature`, `sign`.`signer`
FROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
LEFT JOIN `sign` ON `sign`.`iid` = `item`.`id`
WHERE `item`.`uid` = %d AND `item`.`visible` = 1 AND `item`.`parent` != 0
AND `item`.`wall` = 1 AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
AND ( `item`.`edited` > '%s' OR `item`.`changed` > '%s' )
@ -363,6 +367,22 @@ function get_atom_elements($feed,$item) {
$res['app'] = 'OStatus';
}
// base64 encoded json structure representing Diaspora signature
$dsig = $item->get_item_tags(NAMESPACE_DFRN,'diaspora_signature');
if($dsig) {
$res['dsprsig'] = unxmlify($dsig[0]['data']);
}
$dguid = $item->get_item_tags(NAMESPACE_DFRN,'diaspora_guid');
if($dguid)
$res['guid'] = unxmlify($dguid[0]['data']);
$bm = $item->get_item_tags(NAMESPACE_DFRN,'bookmark');
if($bm)
$res['bookmark'] = ((unxmlify($bm[0]['data']) === 'true') ? 1 : 0);
/**
* If there's a copy of the body content which is guaranteed to have survived mangling in transit, use it.
*/
@ -659,6 +679,15 @@ function encode_rel_links($links) {
function item_store($arr,$force_parent = false) {
// If a Diaspora signature structure was passed in, pull it out of the
// item array and set it aside for later storage.
$dsprsig = null;
if(x($arr,'dsprsig')) {
$dsprsig = json_decode(base64_decode($arr['dsprsig']));
unset($arr['dsprsig']);
}
if($arr['gravity'])
$arr['gravity'] = intval($arr['gravity']);
elseif($arr['parent-uri'] == $arr['uri'])
@ -708,6 +737,7 @@ function item_store($arr,$force_parent = false) {
$arr['deny_cid'] = ((x($arr,'deny_cid')) ? trim($arr['deny_cid']) : '');
$arr['deny_gid'] = ((x($arr,'deny_gid')) ? trim($arr['deny_gid']) : '');
$arr['private'] = ((x($arr,'private')) ? intval($arr['private']) : 0 );
$arr['bookmark'] = ((x($arr,'bookmark')) ? intval($arr['bookmark']) : 0 );
$arr['body'] = ((x($arr,'body')) ? trim($arr['body']) : '');
$arr['tag'] = ((x($arr,'tag')) ? notags(trim($arr['tag'])) : '');
$arr['attach'] = ((x($arr,'attach')) ? notags(trim($arr['attach'])) : '');
@ -835,6 +865,16 @@ function item_store($arr,$force_parent = false) {
intval($current_post)
);
if($dsprsig) {
q("insert into sign (`iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ",
intval($current_post),
dbesc($dsprsig->signed_text),
dbesc($dsprsig->signature),
dbesc($dsprsig->signer)
);
}
/**
* If this is now the last-child, force all _other_ children of this parent to *not* be last-child
*/
@ -894,7 +934,7 @@ function dfrn_deliver($owner,$contact,$atom, $dissolve = false) {
if(! $curl_stat)
return(-1); // timed out
logger('dfrn_deliver: ' . $xml);
logger('dfrn_deliver: ' . $xml, LOGGER_DATA);
if(! $xml)
return 3;
@ -958,7 +998,7 @@ function dfrn_deliver($owner,$contact,$atom, $dissolve = false) {
$key = substr(random_string(),0,16);
$data = bin2hex(aes_encrypt($postvars['data'],$key));
$postvars['data'] = $data;
logger('rino: sent key = ' . $key);
logger('rino: sent key = ' . $key, LOGGER_DEBUG);
if($dfrn_version >= 2.1) {
@ -1670,10 +1710,21 @@ function atom_entry($item,$type,$author,$owner,$comment = false) {
$o .= '<dfrn:private>1</dfrn:private>' . "\r\n";
if($item['extid'])
$o .= '<dfrn:extid>' . $item['extid'] . '</dfrn:extid>' . "\r\n";
$o .= '<dfrn:extid>' . xmlify($item['extid']) . '</dfrn:extid>' . "\r\n";
if($item['bookmark'])
$o .= '<dfrn:bookmark>true</dfrn:bookmark>' . "\r\n";
if($item['app'])
$o .= '<statusnet:notice_info local_id="' . $item['id'] . '" source="' . $item['app'] . '" ></statusnet:notice_info>';
$o .= '<statusnet:notice_info local_id="' . $item['id'] . '" source="' . xmlify($item['app']) . '" ></statusnet:notice_info>' . "\r\n";
if($item['guid'])
$o .= '<dfrn:diaspora_guid>' . $item['guid'] . '</dfrn:diaspora_guid>' . "\r\n";
if($item['signed_text']) {
$sign = base64_encode(json_encode(array('signed_text' => $item['signed_text'],'signature' => $item['signature'],'signer' => $item['signer'])));
$o .= '<dfrn:diaspora_signature>' . xmlify($sign) . '</dfrn:diaspora_signature>' . "\r\n";
}
$verb = construct_verb($item);
$o .= '<as:verb>' . xmlify($verb) . '</as:verb>' . "\r\n";
$actobj = construct_activity_object($item);

View file

@ -81,7 +81,7 @@ function nav(&$a) {
if(! get_config('system','hide_help'))
$nav['help'] = array($help_url, t('Help'), "", t('Help and documentation'));
if($a->apps)
if(count($a->apps)>0)
$nav['apps'] = array('apps', t('Apps'), "", t('Addon applications, utilities, games'));
$nav['search'] = array('search', t('Search'), "", t('Search site content'));
@ -158,6 +158,7 @@ function nav(&$a) {
'$emptynotifications' => t('Nothing new here'),
'$userinfo' => $userinfo,
'$sel' => $a->nav_sel,
'$apps' => $a->apps,
));
call_hooks('page_header', $a->page['nav']);

View file

@ -9,37 +9,37 @@ function fetch_url($url,$binary = false, &$redirects = 0, $timeout = 0) {
$a = get_app();
$ch = curl_init($url);
$ch = @curl_init($url);
if(($redirects > 8) || (! $ch))
return false;
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch, CURLOPT_USERAGENT, "Friendika");
@curl_setopt($ch, CURLOPT_HEADER, true);
@curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
@curl_setopt($ch, CURLOPT_USERAGENT, "Friendika");
if(intval($timeout)) {
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
@curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
}
else {
$curl_time = intval(get_config('system','curl_timeout'));
curl_setopt($ch, CURLOPT_TIMEOUT, (($curl_time !== false) ? $curl_time : 60));
@curl_setopt($ch, CURLOPT_TIMEOUT, (($curl_time !== false) ? $curl_time : 60));
}
// by default we will allow self-signed certs
// but you can override this
$check_cert = get_config('system','verifyssl');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, (($check_cert) ? true : false));
@curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, (($check_cert) ? true : false));
$prx = get_config('system','proxy');
if(strlen($prx)) {
curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);
curl_setopt($ch, CURLOPT_PROXY, $prx);
$prxusr = get_config('system','proxyuser');
@curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);
@curl_setopt($ch, CURLOPT_PROXY, $prx);
$prxusr = @get_config('system','proxyuser');
if(strlen($prxusr))
curl_setopt($ch, CURLOPT_PROXYUSERPWD, $prxusr);
@curl_setopt($ch, CURLOPT_PROXYUSERPWD, $prxusr);
}
if($binary)
curl_setopt($ch, CURLOPT_BINARYTRANSFER,1);
@curl_setopt($ch, CURLOPT_BINARYTRANSFER,1);
$a->set_curl_code(0);
@ -49,7 +49,7 @@ function fetch_url($url,$binary = false, &$redirects = 0, $timeout = 0) {
$s = @curl_exec($ch);
$base = $s;
$curl_info = curl_getinfo($ch);
$curl_info = @curl_getinfo($ch);
$http_code = $curl_info['http_code'];
$header = '';
@ -80,7 +80,7 @@ function fetch_url($url,$binary = false, &$redirects = 0, $timeout = 0) {
$a->set_curl_headers($header);
curl_close($ch);
@curl_close($ch);
return($body);
}}

View file

@ -1,6 +1,21 @@
<?php
require_once("boot.php");
/*
* This file was at one time responsible for doing all deliveries, but this caused
* big problems on shared hosting systems, where the process might get killed by the
* hosting provider and nothing would get delivered.
* It now only delivers one message under certain cases, and invokes a queued
* delivery mechanism (include/deliver.php) to deliver individual contacts at
* controlled intervals.
* This has a much better chance of surviving random processes getting killed
* by the hosting provider.
* A lot of this code is duplicated in include/deliver.php until we have time to go back
* and re-structure the delivery procedure based on the obstacles that have been thrown at
* us by hosting providers.
*/
function notifier_run($argv, $argc){
global $a, $db;
@ -35,7 +50,6 @@ function notifier_run($argv, $argc){
$cmd = $argv[1];
switch($cmd) {
case 'mail':
default:
$item_id = intval($argv[2]);
@ -46,6 +60,8 @@ function notifier_run($argv, $argc){
}
$expire = false;
$mail = false;
$fsuggest = false;
$top_level = false;
$recipients = array();
$url_recipients = array();
@ -54,6 +70,7 @@ function notifier_run($argv, $argc){
if($cmd === 'mail') {
$normal_mode = false;
$mail = true;
$message = q("SELECT * FROM `mail` WHERE `id` = %d LIMIT 1",
intval($item_id)
);
@ -79,6 +96,8 @@ function notifier_run($argv, $argc){
}
elseif($cmd === 'suggest') {
$normal_mode = false;
$fsuggest = true;
$suggest = q("SELECT * FROM `fsuggest` WHERE `id` = %d LIMIT 1",
intval($item_id)
);
@ -104,7 +123,8 @@ function notifier_run($argv, $argc){
$uid = $r[0]['uid'];
$updated = $r[0]['edited'];
$items = q("SELECT * FROM `item` WHERE `parent` = %d ORDER BY `id` ASC",
$items = q("SELECT `item`.*, `sign`.`signed_text`,`sign`.`signature`,`sign`.`signer`
FROM `item` LEFT JOIN `sign` ON `sign`.`iid` = `item`.`id` WHERE `parent` = %d ORDER BY `id` ASC",
intval($parent_id)
);
@ -119,8 +139,11 @@ function notifier_run($argv, $argc){
$item['deleted'] = 1;
}
if(count($items) == 1 && $items[0]['uri'] === $items[0]['parent-uri'])
if((count($items) == 1) && ($items[0]['uri'] === $items[0]['parent-uri'])) {
logger('notifier: top level post');
$top_level = true;
}
}
$r = q("SELECT `contact`.*, `user`.`pubkey` AS `upubkey`, `user`.`prvkey` AS `uprvkey`,
@ -136,6 +159,8 @@ function notifier_run($argv, $argc){
$owner = $r[0];
$walltowall = ((($top_level) && ($owner['id'] != $items[0]['contact-id'])) ? true : false);
$hub = get_config('system','huburl');
// If this is a public conversation, notify the feed hub
@ -144,7 +169,7 @@ function notifier_run($argv, $argc){
// fill this in with a single salmon slap if applicable
$slap = '';
if($cmd != 'mail' && $cmd != 'suggest') {
if(! ($mail || $fsuggest)) {
require_once('include/group.php');
@ -235,7 +260,6 @@ function notifier_run($argv, $argc){
$r = q("SELECT * FROM `contact` WHERE `id` IN ( $conversant_str ) AND `blocked` = 0 AND `pending` = 0");
if(count($r))
$contacts = $r;
}
@ -270,7 +294,7 @@ function notifier_run($argv, $argc){
'$birthday' => $birthday
));
if($cmd === 'mail') {
if($mail) {
$public_message = false; // mail is not public
$body = fix_private_photos($item['body'],$owner['uid']);
@ -286,7 +310,7 @@ function notifier_run($argv, $argc){
'$parent_id' => xmlify($item['parent-uri'])
));
}
elseif($cmd === 'suggest') {
elseif($fsuggest) {
$public_message = false; // suggestions are not public
$sugg_template = get_markup_template('atom_suggest.tpl');
@ -374,17 +398,43 @@ function notifier_run($argv, $argc){
dbesc($recip_str)
);
// delivery loop
require_once('include/salmon.php');
$interval = ((get_config('system','delivery_interval') === false) ? 2 : intval(get_config('system','delivery_interval')));
// delivery loop
if(count($r)) {
foreach($r as $contact) {
if((! $mail) && (! $fsuggest) && (! $followup) && (! $contact['self'])) {
q("insert into deliverq ( `cmd`,`item`,`contact` ) values ('%s', %d, %d )",
dbesc($cmd),
intval($item_id),
intval($contact['id'])
);
}
}
foreach($r as $contact) {
if($contact['self'])
continue;
// potentially more than one recipient. Start a new process and space them out a bit.
// we will deliver single recipient types of message and email receipients here.
if((! $mail) && (! $fsuggest) && (! $followup)) {
proc_run('php','include/delivery.php',$cmd,$item_id,$contact['id']);
if($interval)
@time_sleep_until(microtime(true) + (float) $interval);
continue;
}
$deliver_status = 0;
logger("main delivery by notifier: followup=$followup mail=$mail fsuggest=$fsuggest");
switch($contact['network']) {
case NETWORK_DFRN:
logger('notifier: dfrndelivery: ' . $contact['name']);
@ -558,7 +608,8 @@ function notifier_run($argv, $argc){
diaspora_send_relay($target_item,$owner,$contact);
break;
}
elseif($top_level) {
elseif(($top_level) && (! $walltowall)) {
// currently no workable solution for sending walltowall
diaspora_send_status($target_item,$owner,$contact);
break;
}
@ -589,54 +640,33 @@ function notifier_run($argv, $argc){
}
}
if((strlen($hub)) && ($public_message)) {
$hubs = explode(',', $hub);
if(count($hubs)) {
foreach($hubs as $h) {
$h = trim($h);
if(! strlen($h))
continue;
$params = 'hub.mode=publish&hub.url=' . urlencode($a->get_baseurl() . '/dfrn_poll/' . $owner['nickname'] );
post_url($h,$params);
logger('pubsub: publish: ' . $h . ' ' . $params . ' returned ' . $a->get_curl_code());
if(count($hubs) > 1)
sleep(7); // try and avoid multiple hubs responding at precisely the same time
}
}
}
if($public_message) {
/**
*
* If you have less than 999 dfrn friends and it's a public message,
* we'll just go ahead and push them out securely with dfrn/rino or Diaspora.
* If you've got more than that, you'll have to rely on PuSH delivery.
*
*/
$max_allowed = ((get_config('system','maxpubdeliver') === false) ? 999 : intval(get_config('system','maxpubdeliver')));
/**
*
* Only get the bare essentials and go back for the full record.
* If you've got a lot of friends and we grab all the details at once it could exhaust memory.
*
*/
$r = q("SELECT `id`, `name` FROM `contact`
WHERE `network` in ('%s','%s') AND `uid` = %d AND `blocked` = 0 AND `pending` = 0
AND `rel` != %d ",
AND `rel` != %d order by rand() ",
dbesc(NETWORK_DFRN),
dbesc(NETWORK_DIASPORA),
intval($owner['uid']),
intval(CONTACT_IS_SHARING)
);
if((count($r)) && (($max_allowed == 0) || (count($r) < $max_allowed))) {
if(count($r)) {
logger('pubdeliver: ' . print_r($r,true));
// throw everything into the queue in case we get killed
foreach($r as $rr) {
if((! $mail) && (! $fsuggest) && (! $followup)) {
q("insert into deliverq ( `cmd`,`item`,`contact` ) values ('%s', %d, %d )",
dbesc($cmd),
intval($item_id),
intval($rr['id'])
);
}
}
foreach($r as $rr) {
/* Don't deliver to folks who have already been delivered to */
@ -646,63 +676,32 @@ function notifier_run($argv, $argc){
continue;
}
$n = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1",
intval($rr['id'])
);
if(count($n)) {
$contact = $n[0];
logger('pubdeliver: network: ' . $contact['network']);
switch($contact['network']) {
case NETWORK_DFRN :
logger('notifier: dfrnpubdelivery: ' . $contact['name']);
$deliver_status = dfrn_deliver($owner,$contact,$atom);
break;
case NETWORK_DIASPORA :
require_once('include/diaspora.php');
logger('notifier: diaspora pubdelivery: ' . $contact['name']);
if(get_config('system','dfrn_only') || (! get_config('system','diaspora_enabled')) || (! $normal_mode)) {
logger('notifier: diaspora pubdelivery not allowed at this time');
break;
}
if(! $contact['pubkey']) {
logger('notifier: diaspora pubdelivery: no pubkey');
break;
}
if($target_item['verb'] === ACTIVITY_DISLIKE) {
// unsupported
break;
}
elseif(($target_item['deleted']) && ($target_item['verb'] !== ACTIVITY_LIKE)) {
// diaspora delete,
diaspora_send_retraction($target_item,$owner,$contact);
break;
}
elseif($followup) {
// send comments, likes and retractions of likes to owner to relay
diaspora_send_followup($target_item,$owner,$contact);
break;
}
elseif($target_item['parent'] != $target_item['id']) {
// we are the relay - send comments, likes and unlikes to our conversants
diaspora_send_relay($target_item,$owner,$contact);
break;
}
elseif($top_level) {
diaspora_send_status($target_item,$owner,$contact);
break;
}
default:
break;
}
if((! $mail) && (! $fsuggest) && (! $followup)) {
logger('notifier: delivery agent: ' . $rr['name'] . ' ' . $rr['id']);
proc_run('php','include/delivery.php',$cmd,$item_id,$rr['id']);
if($interval)
@time_sleep_until(microtime(true) + (float) $interval);
}
}
}
if(strlen($hub)) {
$hubs = explode(',', $hub);
if(count($hubs)) {
foreach($hubs as $h) {
$h = trim($h);
if(! strlen($h))
continue;
$params = 'hub.mode=publish&hub.url=' . urlencode($a->get_baseurl() . '/dfrn_poll/' . $owner['nickname'] );
post_url($h,$params);
logger('pubsub: publish: ' . $h . ' ' . $params . ' returned ' . $a->get_curl_code());
if(count($hubs) > 1)
sleep(7); // try and avoid multiple hubs responding at precisely the same time
}
}
}
}
return;

View file

@ -3,18 +3,18 @@ require_once("boot.php");
require_once('include/queue_fn.php');
function queue_run($argv, $argc){
global $a, $db;
global $a, $db;
if(is_null($a)){
$a = new App;
}
if(is_null($a)){
$a = new App;
}
if(is_null($db)){
@include(".htconfig.php");
require_once("dba.php");
$db = new dba($db_host, $db_user, $db_pass, $db_data);
unset($db_host, $db_user, $db_pass, $db_data);
};
if(is_null($db)){
@include(".htconfig.php");
require_once("dba.php");
$db = new dba($db_host, $db_user, $db_pass, $db_data);
unset($db_host, $db_user, $db_pass, $db_data);
};
require_once("session.php");
@ -38,6 +38,18 @@ function queue_run($argv, $argc){
logger('queue: start');
$interval = ((get_config('system','delivery_interval') === false) ? 2 : intval(get_config('system','delivery_interval')));
$r = q("select * from deliverq where 1");
if(count($r)) {
foreach($r as $rr) {
logger('queue: deliverq');
proc_run('php','include/delivery.php',$rr['cmd'],$rr['item'],$rr['contact']);
if($interval)
@time_sleep_until(microtime(true) + (float) $interval);
}
}
$r = q("SELECT `queue`.*, `contact`.`name`, `contact`.`uid` FROM `queue`
LEFT JOIN `contact` ON `queue`.`cid` = `contact`.`id`
WHERE `queue`.`created` < UTC_TIMESTAMP() - INTERVAL 3 DAY");

View file

@ -539,22 +539,30 @@ function contact_block() {
$total = intval($r[0]['total']);
}
if(! $total) {
$o .= '<h4 class="contact-h4">' . t('No contacts') . '</h4>';
return $o;
}
$r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 and `pending` = 0 ORDER BY RAND() LIMIT %d",
intval($a->profile['uid']),
intval($shown)
);
if(count($r)) {
$o .= '<h4 class="contact-h4">' . sprintf( tt('%d Contact','%d Contacts', $total),$total) . '</h4><div id="contact-block">';
foreach($r as $rr) {
$o .= micropro($rr,true,'mpfriend');
}
$o .= '</div><div id="contact-block-end"></div>';
$o .= '<div id="viewcontacts"><a id="viewcontacts-link" href="viewcontacts/' . $a->profile['nickname'] . '">' . t('View Contacts') . '</a></div>';
$contacts = t('No contacts');
$micropro = Null;
} else {
$r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 and `pending` = 0 ORDER BY RAND() LIMIT %d",
intval($a->profile['uid']),
intval($shown)
);
if(count($r)) {
$contacts = sprintf( tt('%d Contact','%d Contacts', $total),$total);
$micropro = Array();
foreach($r as $rr) {
$micropro[] = micropro($rr,true,'mpfriend');
}
}
}
$tpl = get_markup_template('contact_block.tpl');
$o = replace_macros($tpl, array(
'$contacts' => $contacts,
'$nickname' => $a->profile['nickname'],
'$viewcontacts' => t('View Contacts'),
'$micropro' => $micropro,
));
$arr = array('contacts' => $r, 'output' => $o);
@ -602,12 +610,14 @@ function micropro($contact, $redirect = false, $class = '', $textmode = false) {
if(! function_exists('search')) {
function search($s,$id='search-box',$url='/search') {
function search($s,$id='search-box',$url='/search',$save = false) {
$a = get_app();
$o = '<div id="' . $id . '">';
$o .= '<form action="' . $a->get_baseurl() . $url . '" method="get" >';
$o .= '<input type="text" name="search" id="search-text" value="' . $s .'" />';
$o .= '<input type="submit" name="submit" id="search-submit" value="' . t('Search') . '" />';
if($save)
$o .= '<input type="submit" name="save" id="search-save" value="' . t('Save') . '" />';
$o .= '</form></div>';
return $o;
}}

View file

@ -112,10 +112,10 @@ if(! x($_SESSION,'authenticated'))
header('X-Account-Management-Status: none');
if(! x($_SESSION,'sysmsg'))
$_SESSION['sysmsg'] = '';
$_SESSION['sysmsg'] = array();
if(! x($_SESSION,'sysmsg_info'))
$_SESSION['sysmsg_info'] = '';
$_SESSION['sysmsg_info'] = array();
/*
* check_config() is responsible for running update scripts. These automatically
@ -262,7 +262,7 @@ if(isset($homebase))
// now that we've been through the module content, see if the page reported
// a permission problem and if so, a 403 response would seem to be in order.
if(stristr($_SESSION['sysmsg'], t('Permission denied'))) {
if(stristr( implode("",$_SESSION['sysmsg']), t('Permission denied'))) {
header($_SERVER["SERVER_PROTOCOL"] . ' 403 ' . t('Permission denied.'));
}
@ -272,7 +272,7 @@ if(stristr($_SESSION['sysmsg'], t('Permission denied'))) {
*
*/
if(x($_SESSION,'sysmsg')) {
/*if(x($_SESSION,'sysmsg')) {
$a->page['content'] = "<div id=\"sysmsg\" class=\"error-message\">{$_SESSION['sysmsg']}</div>\r\n"
. ((x($a->page,'content')) ? $a->page['content'] : '');
$_SESSION['sysmsg']="";
@ -283,7 +283,7 @@ if(x($_SESSION,'sysmsg_info')) {
. ((x($a->page,'content')) ? $a->page['content'] : '');
$_SESSION['sysmsg_info']="";
unset($_SESSION['sysmsg_info']);
}
}*/

Some files were not shown because too many files have changed in this diff Show more