Merge pull request #1 from friendica/master

Aktualisieren
pull/227/head
gerhard6380 2014-12-14 22:42:38 +01:00
commit 5d33440e63
13 changed files with 1072 additions and 144 deletions

View File

@ -0,0 +1,118 @@
# ADDON appnet
# Copyright (C)
# This file is distributed under the same license as the Friendica appnet addon package.
#
#
# Translators:
# Calango Jr <jcsojr@gmail.com>, 2014
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-06-22 11:47+0200\n"
"PO-Revision-Date: 2014-10-04 04:09+0000\n"
"Last-Translator: Calango Jr <jcsojr@gmail.com>\n"
"Language-Team: Portuguese (Brazil) (http://www.transifex.com/projects/p/friendica/language/pt_BR/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: pt_BR\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: appnet.php:39
msgid "Permission denied."
msgstr "Permissão negada."
#: appnet.php:73
msgid "You are now authenticated to app.net. "
msgstr "Você está autenticado no app.net."
#: appnet.php:77
msgid "<p>Error fetching token. Please try again.</p>"
msgstr "Erro ocorrido na obtenção do token. Tente novamente."
#: appnet.php:80
msgid "return to the connector page"
msgstr "Volte a página de conectores."
#: appnet.php:94
msgid "Post to app.net"
msgstr "Postar no app.net"
#: appnet.php:125 appnet.php:129
msgid "App.net Export"
msgstr "App.net exportar"
#: appnet.php:142
msgid "Currently connected to: "
msgstr "Atualmente conectado em: "
#: appnet.php:144
msgid "Enable App.net Post Plugin"
msgstr "Habilitar App.net Plugin de publicação/postagem"
#: appnet.php:149
msgid "Post to App.net by default"
msgstr "Postar em App.net por padrão"
#: appnet.php:153
msgid "Import the remote timeline"
msgstr "Importar timeline remota"
#: appnet.php:159
msgid ""
"<p>Error fetching user profile. Please clear the configuration and try "
"again.</p>"
msgstr "Erro na obtenção do perfil do usuário. Confira as configurações e tente novamente."
#: appnet.php:164
msgid "<p>You have two ways to connect to App.net.</p>"
msgstr "<p>Você possui duas formas de conectar ao App.net</p>"
#: appnet.php:166
msgid ""
"<p>First way: Register an application at <a "
"href=\"https://account.app.net/developer/apps/\">https://account.app.net/developer/apps/</a>"
" and enter Client ID and Client Secret. "
msgstr "<p>1º Método: Registre uma aplicação em <a href=\"https://account.app.net/developer/apps/\">https://account.app.net/developer/apps/</a> e entre o Client ID e Client Secret"
#: appnet.php:167
#, php-format
msgid "Use '%s' as Redirect URI<p>"
msgstr "Use '%s' como URI redirecionador<p>"
#: appnet.php:169
msgid "Client ID"
msgstr "Client ID"
#: appnet.php:173
msgid "Client Secret"
msgstr "Client Secret"
#: appnet.php:177
msgid ""
"<p>Second way: fetch a token at <a href=\"http://dev-"
"lite.jonathonduerig.com/\">http://dev-lite.jonathonduerig.com/</a>. "
msgstr "<p>2º Método: obtenha um token em <a href=\"http://dev-lite.jonathonduerig.com/\">http://dev-lite.jonathonduerig.com/</a>. "
#: appnet.php:178
msgid ""
"Set these scopes: 'Basic', 'Stream', 'Write Post', 'Public Messages', "
"'Messages'.</p>"
msgstr "Adicione valor as estas saídas: 'Basic', 'Stream', 'Write Post', 'Public Messages', 'Messages'.</p>"
#: appnet.php:180
msgid "Token"
msgstr "Token"
#: appnet.php:192
msgid "Sign in using App.net"
msgstr "Registre-se usando App.net"
#: appnet.php:197
msgid "Clear OAuth configuration"
msgstr "Limpar configuração OAuth"
#: appnet.php:204
msgid "Save Settings"
msgstr "Salvar Configurações"

View File

@ -0,0 +1,29 @@
<?php
if(! function_exists("string_plural_select_pt_br")) {
function string_plural_select_pt_br($n){
return ($n > 1);;
}}
;
$a->strings["Permission denied."] = "Permissão negada.";
$a->strings["You are now authenticated to app.net. "] = "Você está autenticado no app.net.";
$a->strings["<p>Error fetching token. Please try again.</p>"] = "Erro ocorrido na obtenção do token. Tente novamente.";
$a->strings["return to the connector page"] = "Volte a página de conectores.";
$a->strings["Post to app.net"] = "Postar no app.net";
$a->strings["App.net Export"] = "App.net exportar";
$a->strings["Currently connected to: "] = "Atualmente conectado em: ";
$a->strings["Enable App.net Post Plugin"] = "Habilitar App.net Plugin de publicação/postagem";
$a->strings["Post to App.net by default"] = "Postar em App.net por padrão";
$a->strings["Import the remote timeline"] = "Importar timeline remota";
$a->strings["<p>Error fetching user profile. Please clear the configuration and try again.</p>"] = "Erro na obtenção do perfil do usuário. Confira as configurações e tente novamente.";
$a->strings["<p>You have two ways to connect to App.net.</p>"] = "<p>Você possui duas formas de conectar ao App.net</p>";
$a->strings["<p>First way: Register an application at <a href=\"https://account.app.net/developer/apps/\">https://account.app.net/developer/apps/</a> and enter Client ID and Client Secret. "] = "<p>1º Método: Registre uma aplicação em <a href=\"https://account.app.net/developer/apps/\">https://account.app.net/developer/apps/</a> e entre o Client ID e Client Secret";
$a->strings["Use '%s' as Redirect URI<p>"] = "Use '%s' como URI redirecionador<p>";
$a->strings["Client ID"] = "Client ID";
$a->strings["Client Secret"] = "Client Secret";
$a->strings["<p>Second way: fetch a token at <a href=\"http://dev-lite.jonathonduerig.com/\">http://dev-lite.jonathonduerig.com/</a>. "] = "<p>2º Método: obtenha um token em <a href=\"http://dev-lite.jonathonduerig.com/\">http://dev-lite.jonathonduerig.com/</a>. ";
$a->strings["Set these scopes: 'Basic', 'Stream', 'Write Post', 'Public Messages', 'Messages'.</p>"] = "Adicione valor as estas saídas: 'Basic', 'Stream', 'Write Post', 'Public Messages', 'Messages'.</p>";
$a->strings["Token"] = "Token";
$a->strings["Sign in using App.net"] = "Registre-se usando App.net";
$a->strings["Clear OAuth configuration"] = "Limpar configuração OAuth";
$a->strings["Save Settings"] = "Salvar Configurações";

View File

@ -234,8 +234,6 @@ function buffer_send(&$a,&$b) {
if($b['deleted'] || $b['private'] || ($b['created'] !== $b['edited']))
return;
logger("buffer_send: parameter ".print_r($b, true), LOGGER_DATA);
if(! strstr($b['postopts'],'buffer'))
return;
@ -243,8 +241,8 @@ function buffer_send(&$a,&$b) {
return;
// if post comes from buffer don't send it back
if($b['app'] == "Buffer")
return;
//if($b['app'] == "Buffer")
// return;
$client_id = get_config("buffer", "client_id");
$client_secret = get_config("buffer", "client_secret");
@ -258,38 +256,55 @@ function buffer_send(&$a,&$b) {
$profiles = $buffer->go('/profiles');
if (is_array($profiles)) {
logger("Will send these parameter ".print_r($b, true), LOGGER_DEBUG);
foreach ($profiles as $profile) {
if (!$profile->default)
continue;
$send = false;
switch ($profile->service) {
case 'appdotnet':
$send = ($b["extid"] != NETWORK_APPNET);
$limit = 256;
$markup = false;
$includedlinks = true;
$htmlmode = 6;
break;
case 'facebook':
$send = ($b["extid"] != NETWORK_FACEBOOK);
$limit = 0;
$markup = false;
$includedlinks = false;
$htmlmode = 9;
break;
case 'google':
$send = ($b["extid"] != NETWORK_GPLUS);
$limit = 0;
$markup = true;
$includedlinks = false;
$htmlmode = 9;
break;
case 'twitter':
$send = ($b["extid"] != NETWORK_TWITTER);
$limit = 140;
$markup = false;
$includedlinks = true;
$htmlmode = 8;
break;
case 'linkedin':
$send = ($b["extid"] != NETWORK_LINKEDIN);
$limit = 700;
$markup = false;
$includedlinks = true;
$htmlmode = 2;
break;
}
if (!$send)
continue;
$item = $b;
// Markup for Google+
@ -302,7 +317,7 @@ function buffer_send(&$a,&$b) {
$item["body"] = preg_replace("(\[s\](.*?)\[\/s\])ism",'-$1-',$item["body"]);
}
$post = plaintext($a, $item, $limit, $includedlinks);
$post = plaintext($a, $item, $limit, $includedlinks, $htmlmode);
logger("buffer_send: converted message ".$b["id"]." result: ".print_r($post, true), LOGGER_DEBUG);
// The image proxy is used as a sanitizer. Buffer seems to be really picky about pictures
@ -334,6 +349,8 @@ function buffer_send(&$a,&$b) {
$post["text"] .= "\n[".$post["title"]."](".$post["url"].")";
} elseif (($profile->service == "appdotnet") AND isset($post["url"]))
$post["text"] .= " ".$post["url"];
elseif ($profile->service == "google")
$post["text"] .= html_entity_decode("&#x00A0;", ENT_QUOTES, 'UTF-8'); // Send a special blank to identify the post through the "fromgplus" addon
$message = array();
$message["text"] = $post["text"];

View File

@ -428,6 +428,9 @@ function fbpost_post_hook(&$a,&$b) {
logger('fbpost_post_hook: Facebook post first check successful', LOGGER_DEBUG);
// if post comes from facebook don't send it back
if($b['extid'] == NETWORK_FACEBOOK)
return;
if(($b['app'] == "Facebook") AND ($b['verb'] != ACTIVITY_LIKE))
return;
@ -967,9 +970,23 @@ function fbpost_cron($a,$b) {
set_config('facebook','last_poll', time());
}
function fbpost_cleanpicture($url) {
require_once("include/Photo.php");
$urldata = parse_url($url);
if (isset($urldata["query"])) {
parse_str($urldata["query"], $querydata);
if (isset($querydata["url"]) AND (get_photo_info($querydata["url"])))
return($querydata["url"]);
}
return($url);
}
function fbpost_fetchwall($a, $uid) {
require_once("include/oembed.php");
require_once('mod/item.php');
require_once("include/network.php");
require_once("include/items.php");
require_once("mod/item.php");
$access_token = get_pconfig($uid,'facebook','access_token');
$post_to_page = get_pconfig($uid,'facebook','post_to_page');
@ -1019,18 +1036,24 @@ function fbpost_fetchwall($a, $uid) {
$_REQUEST["type"] = "wall";
$_REQUEST["api_source"] = true;
$_REQUEST["profile_uid"] = $uid;
$_REQUEST["source"] = "Facebook";
//$_REQUEST["source"] = "Facebook";
$_REQUEST["source"] = $item->application->name;
$_REQUEST["extid"] = NETWORK_FACEBOOK;
$_REQUEST["title"] = "";
$_REQUEST["body"] = (isset($item->message) ? escape_tags($item->message) : '');
$pagedata = array();
$content = "";
$type = "";
$pagedata["type"] = "";
if(isset($item->name) and isset($item->link)) {
$item->link = original_url($item->link);
$oembed_data = oembed_fetch_url($item->link);
$type = $oembed_data->type;
$pagedata["type"] = $oembed_data->type;
$pagedata["url"] = $item->link;
$pagedata["title"] = $item->name;
$content = "[bookmark=".$item->link."]".$item->name."[/bookmark]";
// If a link is not only attached but also added in the body, look if it can be removed in the body.
@ -1042,67 +1065,71 @@ function fbpost_fetchwall($a, $uid) {
} elseif (isset($item->name))
$content .= "[b]".$item->name."[/b]";
$quote = "";
$pagedata["text"] = "";
if(isset($item->description) and ($item->type != "photo"))
$quote = $item->description;
$pagedata["text"] = $item->description;
if(isset($item->caption) and ($item->type == "photo"))
$quote = $item->caption;
$pagedata["text"] = $item->caption;
// Only import the picture when the message is no video
// oembed display a picture of the video as well
//if ($item->type != "video") {
//if (($item->type != "video") and ($item->type != "photo")) {
if (($type == "") OR ($type == "link")) {
if (($pagedata["type"] == "") OR ($pagedata["type"] == "link")) {
$type = $item->type;
$pagedata["type"] = $item->type;
if (isset($item->picture))
$picture = $item->picture;
$pagedata["images"][0]["src"] = $item->picture;
if (($type == "photo") AND isset($item->object_id)) {
if (($pagedata["type"] == "photo") AND isset($item->object_id)) {
logger('fbpost_fetchwall: fetching fbid '.$item->object_id, LOGGER_DEBUG);
$url = "https://graph.facebook.com/".$item->object_id."?access_token=".$access_token;
$feed = fetch_url($url);
$data = json_decode($feed);
if (isset($data->images)) {
$picture = $data->images[0]->source;
$pagedata["images"][0]["src"] = $data->images[0]->source;
logger('fbpost_fetchwall: got fbid image '.$preview, LOGGER_DEBUG);
}
}
if(($picture != "") && isset($item->link))
$content .= "\n".'[url='.$item->link.'][img]'.$picture.'[/img][/url]';
else {
if ($picture != "")
$content .= "\n".'[img]'.$picture.'[/img]';
if(trim($_REQUEST["body"].$content.$pagedata["text"]) == '') {
logger('facebook: empty body 2 '.$item->id.' '.print_r($item, true));
continue;
}
$pagedata["images"][0]["src"] = fbpost_cleanpicture($pagedata["images"][0]["src"]);
if(($pagedata["images"][0]["src"] != "") && isset($item->link)) {
$item->link = original_url($item->link);
$pagedata["url"] = $item->link;
$content .= "\n".'[url='.$item->link.'][img]'.$pagedata["images"][0]["src"].'[/img][/url]';
} else {
if ($pagedata["images"][0]["src"] != "")
$content .= "\n".'[img]'.$pagedata["images"][0]["src"].'[/img]';
// if just a link, it may be a wall photo - check
if(isset($item->link))
$content .= fbpost_get_photo($uid,$item->link);
}
}
if(trim($_REQUEST["body"].$content.$quote) == '') {
if(trim($_REQUEST["body"].$content.$pagedata["text"]) == '') {
logger('facebook: empty body '.$item->id.' '.print_r($item, true));
continue;
}
if ($pagedata["type"] != "")
$_REQUEST["body"] .= add_page_info_data($pagedata);
else {
if ($content)
$_REQUEST["body"] .= "\n";
$_REQUEST["body"] .= "\n".trim($content);
if ($type)
$_REQUEST["body"] .= "[class=type-".$type."]";
if ($content)
$_REQUEST["body"] .= trim($content);
if ($quote)
$_REQUEST["body"] .= "\n[quote]".$quote."[/quote]";
if ($type)
$_REQUEST["body"] .= "[/class]";
if ($pagedata["text"])
$_REQUEST["body"] .= "\n[quote]".$pagedata["text"]."[/quote]";
$_REQUEST["body"] = trim($_REQUEST["body"]);
}
if (isset($item->place)) {
if ($item->place->name or $item->place->location->street or

View File

@ -216,6 +216,8 @@ function fbsync_createpost($a, $uid, $self, $contacts, $applications, $post, $cr
$access_token = get_pconfig($uid,'facebook','access_token');
require_once("include/oembed.php");
require_once("include/network.php");
require_once("include/items.php");
// check if it was already imported
$r = q("SELECT * FROM `item` WHERE `uid` = %d AND `uri` = '%s' LIMIT 1",
@ -335,15 +337,19 @@ function fbsync_createpost($a, $uid, $self, $contacts, $applications, $post, $cr
break;
}
$pagedata = array();
$content = "";
$type = "";
$pagedata["type"] = "";
if (isset($post->attachment->name) and isset($post->attachment->href)) {
$post->attachment->href = original_url($post->attachment->href);
$oembed_data = oembed_fetch_url($post->attachment->href);
$type = $oembed_data->type;
if ($type == "rich")
$type = "link";
$pagedata["type"] = $oembed_data->type;
if ($pagedata["type"] == "rich")
$pagedata["type"] = "link";
$pagedata["url"] = $post->attachment->href;
$pagedata["title"] = $post->attachment->name;
$content = "[bookmark=".$post->attachment->href."]".$post->attachment->name."[/bookmark]";
// If a link is not only attached but also added in the body, look if it can be removed in the body.
@ -355,28 +361,28 @@ function fbsync_createpost($a, $uid, $self, $contacts, $applications, $post, $cr
} elseif (isset($post->attachment->name) AND ($post->attachment->name != ""))
$content = "[b]" . $post->attachment->name."[/b]";
$quote = "";
$pagedata["text"] = "";
if (isset($post->attachment->description) and ($post->attachment->fb_object_type != "photo"))
$quote = $post->attachment->description;
$pagedata["text"] = $post->attachment->description;
if (isset($post->attachment->caption) and ($post->attachment->fb_object_type == "photo"))
$quote = $post->attachment->caption;
$pagedata["text"] = $post->attachment->caption;
if ($quote.$post->attachment->href.$content.$postarray["body"] == "")
if ($pagedata["text"].$post->attachment->href.$content.$postarray["body"] == "")
return;
if (isset($post->attachment->media) AND (($type == "") OR ($type == "link"))) {
if (isset($post->attachment->media) AND (($pagedata["type"] == "") OR ($pagedata["type"] == "link"))) {
foreach ($post->attachment->media AS $media) {
if (isset($media->type))
$type = $media->type;
$pagedata["type"] = $media->type;
if (isset($media->src))
$preview = $media->src;
$pagedata["images"][0]["src"] = $media->src;
if (isset($media->photo)) {
if (isset($media->photo->images) AND (count($media->photo->images) > 1))
$preview = $media->photo->images[1]->src;
$pagedata["images"][0]["src"] = $media->photo->images[1]->src;
if (isset($media->photo->fbid)) {
logger('fbsync_createpost: fetching fbid '.$media->photo->fbid, LOGGER_DEBUG);
@ -384,18 +390,22 @@ function fbsync_createpost($a, $uid, $self, $contacts, $applications, $post, $cr
$feed = fetch_url($url);
$data = json_decode($feed);
if (isset($data->images)) {
$preview = $data->images[0]->source;
logger('fbsync_createpost: got fbid '.$media->photo->fbid.' image '.$preview, LOGGER_DEBUG);
$pagedata["images"][0]["src"] = $data->images[0]->source;
logger('fbsync_createpost: got fbid '.$media->photo->fbid.' image '.$pagedata["images"][0]["src"], LOGGER_DEBUG);
} else
logger('fbsync_createpost: error fetching fbid '.$media->photo->fbid.' '.print_r($data, true), LOGGER_DEBUG);
}
}
if (isset($media->href) AND ($preview != "") AND ($media->href != ""))
$content .= "\n".'[url='.$media->href.'][img]'.$preview.'[/img][/url]';
else {
if ($preview != "")
$content .= "\n".'[img]'.$preview.'[/img]';
$pagedata["images"][0]["src"] = fbpost_cleanpicture($pagedata["images"][0]["src"]);
if (isset($media->href) AND ($pagedata["images"][0]["src"] != "") AND ($media->href != "")) {
$media->href = original_url($media->href);
$pagedata["url"] = $media->href;
$content .= "\n".'[url='.$media->href.'][img]'.$pagedata["images"][0]["src"].'[/img][/url]';
} else {
if ($pagedata["images"][0]["src"] != "")
$content .= "\n".'[img]'.$pagedata["images"][0]["src"].'[/img]';
// if just a link, it may be a wall photo - check
if (isset($post->link))
@ -404,25 +414,20 @@ function fbsync_createpost($a, $uid, $self, $contacts, $applications, $post, $cr
}
}
if ($type == "link")
if ($pagedata["type"] != "") {
if ($pagedata["type"] == "link")
$postarray["object-type"] = ACTIVITY_OBJ_BOOKMARK;
$postarray["body"] .= add_page_info_data($pagedata);
} else {
if ($content)
$postarray["body"] .= "\n";
$postarray["body"] .= "\n".trim($content);
if ($type)
$postarray["body"] .= "[class=type-".$type."]";
if ($content)
$postarray["body"] .= trim($content);
if ($quote)
$postarray["body"] .= "\n[quote]".trim($quote)."[/quote]";
if ($type)
$postarray["body"] .= "[/class]";
if ($pagedata["text"])
$postarray["body"] .= "\n[quote]".trim($pagedata["text"])."[/quote]";
$postarray["body"] = trim($postarray["body"]);
}
if (trim($postarray["body"]) == "")
return;

View File

@ -138,6 +138,7 @@ function fromgplus_post($a, $uid, $source, $body, $location) {
$_REQUEST['profile_uid'] = $uid;
$_REQUEST['source'] = $source;
$_REQUEST['extid'] = NETWORK_GPLUS;
// $_REQUEST['verb']
// $_REQUEST['parent']
@ -275,29 +276,36 @@ function fromgplus_cleantext($text) {
function fromgplus_handleattachments($a, $uid, $item, $displaytext, $shared) {
require_once("include/Photo.php");
require_once("include/items.php");
require_once("include/network.php");
$post = "";
$quote = "";
$type = "";
$pagedata = array();
$pagedata["type"] = "";
foreach ($item->object->attachments as $attachment) {
switch($attachment->objectType) {
case "video":
$post .= "\n[class=type-video][bookmark=".$attachment->url."]".fromgplus_html2bbcode($attachment->displayName)."[/bookmark]\n[/class]";
$pagedata["type"] = "video";
$pagedata["url"] = original_url($attachment->url);
$pagedata["title"] = fromgplus_html2bbcode($attachment->displayName);
break;
case "article":
$post .= "\n[class=type-link][bookmark=".$attachment->url."]".fromgplus_html2bbcode($attachment->displayName)."[/bookmark]\n";
$pagedata["type"] = "link";
$pagedata["url"] = original_url($attachment->url);
$pagedata["title"] = fromgplus_html2bbcode($attachment->displayName);
$images = fromgplus_cleanupgoogleproxy($attachment->fullImage, $attachment->image);
if ($images["full"] != "")
$post .= "\n[img]".$images["full"]."[/img]";
$pagedata["images"][0]["src"] = $images["full"];
$quote = trim(fromgplus_html2bbcode($attachment->content));
if ($quote != "")
$quote = "\n[quote]".$quote."[/quote]";
$quote .= "[/class]";
if ($quote != "")
$pagedata["text"] = $quote;
break;
case "photo":
@ -311,52 +319,72 @@ function fromgplus_handleattachments($a, $uid, $item, $displaytext, $shared) {
$images = store_photo($a, $uid, "", $attachment->image->url);
}
if ($images["preview"] != "")
if ($images["preview"] != "") {
$post .= "\n[url=".$images["page"]."][img]".$images["preview"]."[/img][/url]\n";
elseif ($images["full"] != "")
$pagedata["images"][0]["src"] = $images["preview"];
$pagedata["url"] = $images["page"];
} elseif ($images["full"] != "") {
$post .= "\n[img]".$images["full"]."[/img]\n";
$pagedata["images"][0]["src"] = $images["full"];
if (($attachment->displayName != "") AND (fromgplus_cleantext($attachment->displayName) != fromgplus_cleantext($displaytext)))
if ($images["preview"] != "")
$pagedata["images"][1]["src"] = $images["preview"];
}
if (($attachment->displayName != "") AND (fromgplus_cleantext($attachment->displayName) != fromgplus_cleantext($displaytext))) {
$post .= fromgplus_html2bbcode($attachment->displayName)."\n";
$pagedata["title"] = fromgplus_html2bbcode($attachment->displayName);
}
break;
case "photo-album":
$post .= "\n\n[bookmark=".$attachment->url."]".fromgplus_html2bbcode($attachment->displayName)."[/bookmark]\n";
$pagedata["url"] = original_url($attachment->url);
$pagedata["title"] = fromgplus_html2bbcode($attachment->displayName);
$post .= "\n\n[bookmark=".$pagedata["url"]."]".$pagedata["title"]."[/bookmark]\n";
$images = fromgplus_cleanupgoogleproxy($attachment->fullImage, $attachment->image);
if ($images["preview"] != "")
$post .= "\n[url=".$images["full"]."][img]".$images["preview"]."[/img][/url]\n";
elseif ($images["full"] != "")
$post .= "\n[img]".$images["full"]."[/img]\n";
if ($images["preview"] != "") {
$post .= "\n[url=".$images["full"]."][img]".$images["preview"]."[/img][/url]\n";
$pagedata["images"][0]["src"] = $images["preview"];
$pagedata["url"] = $images["full"];
} elseif ($images["full"] != "") {
$post .= "\n[img]".$images["full"]."[/img]\n";
$pagedata["images"][0]["src"] = $images["full"];
if ($images["preview"] != "")
$pagedata["images"][1]["src"] = $images["preview"];
}
break;
case "album":
$post .= "\n[class=type-link][bookmark=".$attachment->url."]".fromgplus_html2bbcode($attachment->displayName)."[/bookmark]";
$pagedata["type"] = "link";
$pagedata["url"] = original_url($attachment->url);
$pagedata["title"] = fromgplus_html2bbcode($attachment->displayName);
$thumb = $attachment->thumbnails[0];
$post .= "\n[img]".$thumb->image->url."[/img]";
$pagedata["images"][0]["src"] = $thumb->image->url;
$quote = trim(fromgplus_html2bbcode($thumb->description));
if ($quote != "")
$quote = "\n[quote]".$quote."[/quote]";
$pagedata["text"] = $quote;
//foreach($attachment->thumbnails as $thumb) {
// $preview = "/w".$thumb->image->width."-h".$thumb->image->height."/";
// $preview2 = "/w".$thumb->image->width."-h".$thumb->image->height."-p/";
// $image = str_replace(array($preview, $preview2), array("/", "/"), $thumb->image->url);
// $post .= "\n[url=".$thumb->url."][img]".$image."[/img][/url]\n";
//}
$quote .= "[/class]";
break;
case "audio":
$post .= "\n\n[bookmark=".$attachment->url."]".fromgplus_html2bbcode($attachment->displayName)."[/bookmark]\n";
$pagedata["url"] = original_url($attachment->url);
$pagedata["title"] = fromgplus_html2bbcode($attachment->displayName);
$post .= "\n\n[bookmark=".$pagedata["url"]."]".$pagedata["title"]."[/bookmark]\n";
break;
//default:
// die($attachment->objectType);
}
}
if ($pagedata["type"] != "")
return(add_page_info_data($pagedata));
return($post.$quote);
}

View File

@ -0,0 +1,109 @@
<?php
/**
* Name: Leistungsschutzrecht
* Description: Only useful in germany: Remove data from snippets from members of the VG Media
* Version: 0.1
* Author: Michael Vogel <https://pirati.ca/profile/heluecht>
*/
function leistungsschutzrecht_install() {
register_hook('cron', 'addon/leistungsschutzrecht/leistungsschutzrecht.php', 'leistungsschutzrecht_cron');
register_hook('getsiteinfo', 'addon/leistungsschutzrecht/leistungsschutzrecht.php', 'leistungsschutzrecht_getsiteinfo');
register_hook('page_info_data', 'addon/leistungsschutzrecht/leistungsschutzrecht.php', 'leistungsschutzrecht_getsiteinfo');
}
function leistungsschutzrecht_uninstall() {
unregister_hook('cron', 'addon/leistungsschutzrecht/leistungsschutzrecht.php', 'leistungsschutzrecht_cron');
unregister_hook('getsiteinfo', 'addon/leistungsschutzrecht/leistungsschutzrecht.php', 'leistungsschutzrecht_getsiteinfo');
unregister_hook('page_info_data', 'addon/leistungsschutzrecht/leistungsschutzrecht.php', 'leistungsschutzrecht_getsiteinfo');
}
function leistungsschutzrecht_getsiteinfo($a, &$siteinfo) {
if (!isset($siteinfo["url"]))
return;
if (!leistungsschutzrecht_is_member_site($siteinfo["url"]))
return;
$siteinfo["title"] = $siteinfo["url"];
unset($siteinfo["text"]);
unset($siteinfo["image"]);
unset($siteinfo["images"]);
unset($siteinfo["keywords"]);
}
function leistungsschutzrecht_fetchsites() {
require_once("include/network.php");
$sites = array();
$url = "http://www.vg-media.de/lizenzen/digitale-verlegerische-angebote/wahrnehmungsberechtigte-digitale-verlegerische-angebote.html";
$site = fetch_url($url);
$doc = new DOMDocument();
@$doc->loadHTML($site);
$xpath = new DomXPath($doc);
$list = $xpath->query("//td/a");
foreach ($list as $node) {
$attr = array();
if ($node->attributes->length)
foreach ($node->attributes as $attribute)
$attr[$attribute->name] = $attribute->value;
if (isset($attr["href"])) {
$urldata = parse_url($attr["href"]);
if (isset($urldata["host"]) AND !isset($urldata["path"])) {
$cleanedurlpart = explode("%", $urldata["host"]);
$hostname = explode(".", $cleanedurlpart[0]);
$site = $hostname[sizeof($hostname) - 2].".".$hostname[sizeof($hostname) - 1];
$sites[$site] = $site;
}
}
}
if (sizeof($sites)) {
set_config('leistungsschutzrecht','sites',$sites);
}
}
function leistungsschutzrecht_is_member_site($url) {
$sites = get_config('leistungsschutzrecht','sites');
if ($sites == "")
return(false);
if (sizeof($sites) == 0)
return(false);
$urldata = parse_url($url);
if (!isset($urldata["host"]))
return(false);
$cleanedurlpart = explode("%", $urldata["host"]);
$hostname = explode(".", $cleanedurlpart[0]);
$site = $hostname[sizeof($hostname) - 2].".".$hostname[sizeof($hostname) - 1];
return (isset($sites[$site]));
}
function leistungsschutzrecht_cron($a,$b) {
$last = get_config('leistungsschutzrecht','last_poll');
if($last) {
$next = $last + 86400;
if($next > time()) {
logger('poll intervall not reached');
return;
}
}
leistungsschutzrecht_fetchsites();
set_config('leistungsschutzrecht','last_poll', time());
}
?>

View File

@ -433,8 +433,8 @@ function pumpio_send(&$a,&$b) {
$title = trim($b['title']);
if ($title != '')
$title = "<h4>".$title."</h4>";
//if ($title != '')
// $title = "<h4>".$title."</h4>";
$content = bbcode($b['body'], false, false, 4);
@ -454,7 +454,10 @@ function pumpio_send(&$a,&$b) {
if (!$iscomment) {
$params["object"] = array(
'objectType' => "note",
'content' => $title.$content);
'content' => $content);
if ($title != "")
$params["object"]["displayName"] = $title;
if (count($receiver["to"]))
$params["to"] = $receiver["to"];
@ -477,8 +480,11 @@ function pumpio_send(&$a,&$b) {
$params["object"] = array(
'objectType' => "comment",
'content' => $title.$content,
'content' => $content,
'inReplyTo' => $inReplyTo);
if ($title != "")
$params["object"]["displayName"] = $title;
}
$client = new oauth_client_class;
@ -805,7 +811,8 @@ function pumpio_dounlike(&$a, $uid, $self, $post, $own_id) {
logger("pumpio_dounlike: not found. User ".$own_id." ".$uid." Contact: ".$contactid." Url ".$orig_post['uri']);
}
function pumpio_dolike(&$a, $uid, $self, $post, $own_id) {
function pumpio_dolike(&$a, $uid, $self, $post, $own_id, $threadcompletion = true) {
require_once('include/items.php');
// Searching for the liked post
// Two queries for speed issues
@ -828,6 +835,10 @@ function pumpio_dolike(&$a, $uid, $self, $post, $own_id) {
$orig_post = $r[0];
}
// thread completion
if ($threadcompletion)
pumpio_fetchallcomments($a, $uid, $post->object->id);
$contactid = 0;
if(link_compare($post->actor->url, $own_id)) {
@ -1032,7 +1043,7 @@ function pumpio_dodelete(&$a, $uid, $self, $post, $own_id) {
return drop_item($r[0]["id"], $false);
}
function pumpio_dopost(&$a, $client, $uid, $self, $post, $own_id, $threadcompletion = false) {
function pumpio_dopost(&$a, $client, $uid, $self, $post, $own_id, $threadcompletion = true) {
require_once('include/items.php');
require_once('include/html2bbcode.php');
@ -1094,6 +1105,11 @@ function pumpio_dopost(&$a, $client, $uid, $self, $post, $own_id, $threadcomplet
$contact_id = $self[0]['id'];
$postarray['parent-uri'] = $post->object->id;
if (!$public) {
$postarray['private'] = 1;
$postarray['allow_cid'] = '<' . $self[0]['id'] . '>';
}
} else {
$contact_id = 0;
@ -1139,7 +1155,7 @@ function pumpio_dopost(&$a, $client, $uid, $self, $post, $own_id, $threadcomplet
$reply->published = $post->object->inReplyTo->published;
$reply->received = $post->object->inReplyTo->updated;
$reply->url = $post->object->inReplyTo->url;
pumpio_dopost($a, $client, $uid, $self, $reply, $own_id);
pumpio_dopost($a, $client, $uid, $self, $reply, $own_id, false);
$postarray['parent-uri'] = $post->object->inReplyTo->id;
}
@ -1167,10 +1183,6 @@ function pumpio_dopost(&$a, $client, $uid, $self, $post, $own_id, $threadcomplet
$postarray['created'] = datetime_convert('UTC','UTC',$post->published);
$postarray['edited'] = datetime_convert('UTC','UTC',$post->received);
if (!$public) {
$postarray['private'] = 1;
$postarray['allow_cid'] = '<' . $self[0]['id'] . '>';
}
if ($post->verb == "share") {
if (!intval(get_config('system','wall-to-wall_share'))) {
@ -1276,6 +1288,13 @@ function pumpio_fetchinbox(&$a, $uid) {
$self = q("SELECT * FROM `contact` WHERE `self` = 1 AND `uid` = %d LIMIT 1",
intval($uid));
$lastitems = q("SELECT uri FROM `item` WHERE `network` = '%s' AND `uid` = %d AND
`extid` != '' AND `id` = `parent`
ORDER BY `commented` DESC LIMIT 10",
dbesc(NETWORK_PUMPIO),
intval($uid)
);
$client = new oauth_client_class;
$client->oauth_version = '1.0a';
$client->authorization_header = true;
@ -1301,10 +1320,13 @@ function pumpio_fetchinbox(&$a, $uid) {
if (count($posts))
foreach ($posts as $post) {
$last_id = $post->id;
pumpio_dopost($a, $client, $uid, $self, $post, $own_id);
pumpio_dopost($a, $client, $uid, $self, $post, $own_id, true);
}
}
foreach ($lastitems AS $item)
pumpio_fetchallcomments($a, $uid, $item["uri"]);
set_pconfig($uid,'pumpio','last_id', $last_id);
}
@ -1512,33 +1534,23 @@ function pumpio_fetchallcomments(&$a, $uid, $id) {
$hostname = get_pconfig($uid, 'pumpio','host');
$username = get_pconfig($uid, "pumpio", "user");
$own_id = "https://".$hostname."/".$username;
logger("pumpio_fetchallcomments: completing comment for user ".$uid." post id ".$id);
logger("pumpio_fetchallcomments: completing comment for user ".$uid." url ".$url);
$own_id = "https://".$hostname."/".$username;
$self = q("SELECT * FROM `contact` WHERE `self` = 1 AND `uid` = %d LIMIT 1",
intval($uid));
// Fetching the original post - Two queries for speed issues
$r = q("SELECT extid FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
dbesc($url),
intval($uid)
);
if (!count($r)) {
$r = q("SELECT extid FROM `item` WHERE `extid` = '%s' AND `uid` = %d LIMIT 1",
dbesc($url),
// Fetching the original post
$r = q("SELECT `extid` FROM `item` WHERE `uri` = '%s' AND `uid` = %d AND `extid` != '' LIMIT 1",
dbesc($id),
intval($uid)
);
if (!count($r))
return false;
}
if ($r[0]["extid"])
$url = $r[0]["extid"];
else
$url = $id;
$client = new oauth_client_class;
$client->oauth_version = '1.0a';
@ -1557,6 +1569,22 @@ function pumpio_fetchallcomments(&$a, $uid, $id) {
if (!$success)
return;
if ($item->likes->totalItems != 0) {
foreach ($item->likes->items AS $post) {
$like = new stdClass;
$like->object = new stdClass;
$like->object->id = $item->id;
$like->actor = new stdClass;
$like->actor->displayName = $item->displayName;
$like->actor->preferredUsername = $item->preferredUsername;
$like->actor->url = $item->url;
$like->actor->image = $item->image;
$like->generator = new stdClass;
$like->generator->displayName = "pumpio";
pumpio_dolike($a, $uid, $self, $post, $own_id, false);
}
}
if ($item->replies->totalItems == 0)
return;
@ -1566,7 +1594,7 @@ function pumpio_fetchallcomments(&$a, $uid, $id) {
// Checking if the comment already exists - Two queries for speed issues
$r = q("SELECT extid FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
dbesc($url),
dbesc($item->id),
intval($uid)
);
@ -1574,18 +1602,21 @@ function pumpio_fetchallcomments(&$a, $uid, $id) {
continue;
$r = q("SELECT extid FROM `item` WHERE `extid` = '%s' AND `uid` = %d LIMIT 1",
dbesc($url),
dbesc($item->id),
intval($uid)
);
if (count($r))
continue;
$post = new stdClass;
$post->verb = "post";
$post->actor = $item->author;
$post->published = $item->published;
$post->received = $item->updated;
$post->generator = new stdClass;
$post->generator->displayName = "pumpio";
// To-Do: Check for public post
unset($item->author);
unset($item->published);
@ -1593,17 +1624,13 @@ function pumpio_fetchallcomments(&$a, $uid, $id) {
$post->object = $item;
logger("pumpio_fetchallcomments: posting comment ".$post->object->id);
logger("pumpio_fetchallcomments: posting comment ".$post->object->id." ".print_r($post, true));
pumpio_dopost($a, $client, $uid, $self, $post, $own_id, false);
}
}
/*
Bugs:
- refresh after post doesn't always happen
To-Do:
- edit own notes
- delete own notes
*/

View File

@ -532,6 +532,9 @@ function statusnet_post_hook(&$a,&$b) {
return;
// if posts comes from statusnet don't send it back
if($b['extid'] == NETWORK_STATUSNET)
return;
if($b['app'] == "StatusNet")
return;
@ -829,7 +832,9 @@ function statusnet_fetchtimeline($a, $uid) {
$_REQUEST["type"] = "wall";
$_REQUEST["api_source"] = true;
$_REQUEST["profile_uid"] = $uid;
$_REQUEST["source"] = "StatusNet";
//$_REQUEST["source"] = "StatusNet";
$_REQUEST["source"] = $post->source;
$_REQUEST["extid"] = NETWORK_STATUSNET;
//$_REQUEST["date"] = $post->created_at;
@ -872,6 +877,9 @@ function statusnet_address($contact) {
}
function statusnet_fetch_contact($uid, $contact, $create_user) {
if ($contact->statusnet_profile_url == "")
return(-1);
// Check if the unique contact is existing
// To-Do: only update once a while
$r = q("SELECT id FROM unique_contacts WHERE url='%s' LIMIT 1",
@ -950,16 +958,12 @@ function statusnet_fetch_contact($uid, $contact, $create_user) {
q("UPDATE `contact` SET `photo` = '%s',
`thumb` = '%s',
`micro` = '%s',
`name-date` = '%s',
`uri-date` = '%s',
`avatar-date` = '%s'
WHERE `id` = %d",
dbesc($photos[0]),
dbesc($photos[1]),
dbesc($photos[2]),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
intval($contact_id)
);
@ -1338,7 +1342,16 @@ function statusnet_fetchhometimeline($a, $uid) {
$items = $connection->get('statuses/home_timeline', $parameters);
if (!is_array($items)) {
logger("statusnet_fetchhometimeline: Error fetching home timeline: ".print_r($items, true), LOGGER_DEBUG);
if (is_object($items) AND isset($items->error))
$errormsg = $items->error;
elseif (is_object($items))
$errormsg = print_r($items, true);
elseif (is_string($items) OR is_float($items) OR is_int($items))
$errormsg = $items;
else
$errormsg = "Unknown error";
logger("statusnet_fetchhometimeline: Error fetching home timeline: ".$errormsg, LOGGER_DEBUG);
return;
}

View File

@ -438,6 +438,9 @@ function twitter_post_hook(&$a,&$b) {
return;
// if post comes from twitter don't send it back
if($b['extid'] == NETWORK_TWITTER)
return;
if($b['app'] == "Twitter")
return;
@ -743,7 +746,9 @@ function twitter_fetchtimeline($a, $uid) {
$_REQUEST["type"] = "wall";
$_REQUEST["api_source"] = true;
$_REQUEST["profile_uid"] = $uid;
$_REQUEST["source"] = "Twitter";
//$_REQUEST["source"] = "Twitter";
$_REQUEST["source"] = $post->source;
$_REQUEST["extid"] = NETWORK_TWITTER;
//$_REQUEST["date"] = $post->created_at;
@ -892,6 +897,9 @@ function twitter_queue_hook(&$a,&$b) {
function twitter_fetch_contact($uid, $contact, $create_user) {
require_once("include/Photo.php");
if ($contact->id_str == "")
return(-1);
$avatar = str_replace("_normal.", ".", $contact->profile_image_url_https);
$info = get_photo_info($avatar);

View File

@ -0,0 +1,38 @@
# ADDON windowsphonepush
# Copyright (C)
# This file is distributed under the same license as the Friendica windowsphonepush addon package.
#
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-10-26 15:02+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: windowsphonepush.php:85
msgid "WindowsPhonePush settings updated."
msgstr ""
#: windowsphonepush.php:114
msgid "WindowsPhonePush Settings"
msgstr ""
#: windowsphonepush.php:117
msgid "Enable WindowsPhonePush Plugin"
msgstr ""
#: windowsphonepush.php:122
msgid "Push text of new item"
msgstr ""
#: windowsphonepush.php:127
msgid "Save Settings"
msgstr ""

View File

@ -0,0 +1,36 @@
#windowsphonepush-device_url-wrapper {
margin-top: 25px;
}
#windowsphonepush-enable-label {
float: left;
width: 200px;
margin-bottom: 25px;
}
#windowsphonepush-enable-chk {
float: left;
}
#windowsphonepush-device_url-label {
float: left;
width: 200px;
margin-bottom: 25px;
}
#windowsphonepush-device_url-text {
float: left;
background-color: #C0C0C0;
width: 500px;
}
#windowsphonepush-senditemtext-label {
float: left;
width: 200px;
margin-bottom: 25px;
}
#windowsphonepush-senditemtext-chk {
float: left;
}

View File

@ -0,0 +1,473 @@
<?php
/**
* Name: WindowsPhonePush
* Description: Enable push notification to send information to Friendica Mobile app on Windows phone (count of unread timeline entries, text of last posting - if wished by user)
* Version: 1.0
* Author: Gerhard Seeber <http://friendica.seeber.at/profile/admin>
*
*
* Pre-requisite: Windows Phone mobile device (at least WP 7.0)
* Friendica mobile app on Windows Phone
*
* When plugin is installed, the system calls the plugin
* name_install() function, located in 'addon/name/name.php',
* where 'name' is the name of the addon.
* If the addon is removed from the configuration list, the
* system will call the name_uninstall() function.
*
*/
function windowsphonepush_install() {
/**
*
* Our plugin will attach in three places.
* The first is within cron - so the push notifications will be
* sent every 10 minutes (or whatever is set in crontab).
*
*/
register_hook('cron', 'addon/windowsphonepush/windowsphonepush.php', 'windowsphonepush_cron');
/**
*
* Then we'll attach into the plugin settings page, and also the
* settings post hook so that we can create and update
* user preferences. User shall be able to activate the plugin and
* define whether he allows pushing first characters of item text
*
*/
register_hook('plugin_settings', 'addon/windowsphonepush/windowsphonepush.php', 'windowsphonepush_settings');
register_hook('plugin_settings_post', 'addon/windowsphonepush/windowsphonepush.php', 'windowsphonepush_settings_post');
logger("installed windowsphonepush");
}
function windowsphonepush_uninstall() {
/**
*
* uninstall unregisters any hooks created with register_hook
* during install. Don't delete data in table `pconfig`.
*
*/
unregister_hook('cron', 'addon/windowsphonepush/windowsphonepush.php', 'windowsphonepush_cron');
unregister_hook('plugin_settings', 'addon/windowsphonepush/windowsphonepush.php', 'windowsphonepush_settings');
unregister_hook('plugin_settings_post', 'addon/windowsphonepush/windowsphonepush.php', 'windowsphonepush_settings_post');
logger("removed windowsphonepush");
}
/* declare the windowsphonepush function so that /windowsphonepush url requests will land here */
function windowsphonepush_module() {}
/**
*
* Callback from the settings post function.
* $post contains the $_POST array.
* We will make sure we've got a valid user account
* and if so set our configuration setting for this person.
*
*/
function windowsphonepush_settings_post($a,$post) {
if(! local_user() || (! x($_POST,'windowsphonepush-submit')))
return;
set_pconfig(local_user(),'windowsphonepush','enable',intval($_POST['windowsphonepush']));
set_pconfig(local_user(),'windowsphonepush','senditemtext',intval($_POST['windowsphonepush-senditemtext']));
info( t('WindowsPhonePush settings updated.') . EOL);
}
/**
*
* Called from the Plugin Setting form.
* Add our own settings info to the page.
*
*/
function windowsphonepush_settings(&$a,&$s) {
if(! local_user())
return;
/* Add our stylesheet to the page so we can make our settings look nice */
$a->page['htmlhead'] .= '<link rel="stylesheet" type="text/css" href="' . $a->get_baseurl() . '/addon/windowsphonepush/windowsphonepush.css' . '" media="all" />' . "\r\n";
/* Get the current state of our config variables */
$enabled = get_pconfig(local_user(),'windowsphonepush','enable');
$checked_enabled = (($enabled) ? ' checked="checked" ' : '');
$senditemtext = get_pconfig(local_user(), 'windowsphonepush', 'senditemtext');
$checked_senditemtext = (($senditemtext) ? ' checked="checked" ' : '');
$device_url = get_pconfig(local_user(), 'windowsphonepush', 'device_url');
/* Add some HTML to the existing form */
$s .= '<div class="settings-block">';
$s .= '<h3>' . t('WindowsPhonePush Settings') . '</h3>';
$s .= '<div id="windowsphonepush-enable-wrapper">';
$s .= '<label id="windowsphonepush-enable-label" for="windowsphonepush-enable-chk">' . t('Enable WindowsPhonePush Plugin') . '</label>';
$s .= '<input id="windowsphonepush-enable-chk" type="checkbox" name="windowsphonepush" value="1" ' . $checked_enabled . '/>';
$s .= '</div><div class="clear"></div>';
$s .= '<div id="windowsphonepush-senditemtext-wrapper">';
$s .= '<label id="windowsphonepush-senditemtext-label" for="windowsphonepush-senditemtext-chk">' . t('Push text of new item') . '</label>';
$s .= '<input id="windowsphonepush-senditemtext-chk" type="checkbox" name="windowsphonepush-senditemtext" value="1" ' . $checked_senditemtext . '/>';
$s .= '</div><div class="clear"></div>';
/* provide a submit button - enable und senditemtext can be changed by the user*/
$s .= '<div class="settings-submit-wrapper" ><input type="submit" id="windowsphonepush-submit" name="windowsphonepush-submit" class="settings-submit" value="' . t('Save Settings') . '" /></div><div class="clear"></div>';
/* provide further read-only information concerning the addon (useful for */
$s .= '<div id="windowsphonepush-device_url-wrapper">';
$s .= '<label id="windowsphonepush-device_url-label" for="windowsphonepush-device_url-text">Device-URL</label>';
$s .= '<input id="windowsphonepush-device_url-text" type="text" readonly value=' . $device_url . '/>';
$s .= '</div><div class="clear"></div></div>';
return;
}
/**
*
* Cron function used to regularly check all users on the server with active windowsphonepushplugin and send
* notifications to the Microsoft servers and consequently to the Windows Phone device
*
*/
function windowsphonepush_cron() {
// retrieve all UID's for which the plugin windowsphonepush is enabled and loop through every user
$r = q("SELECT * FROM `pconfig` WHERE `cat` = 'windowsphonepush' AND `k` = 'enable' AND `v` = 1");
if(count($r)) {
foreach($r as $rr) {
// load stored information for the user-id of the current loop
$device_url = get_pconfig($rr['uid'], 'windowsphonepush', 'device_url');
$lastpushid = get_pconfig($rr['uid'], 'windowsphonepush', 'lastpushid');
// pushing only possible if device_url (the URI on Microsoft server) is available or not "NA" (which will be sent
// by app if user has switched the server setting in app - sending blank not possible as this would return an update error)
if ( ( $device_url == "" ) || ( $device_url == "NA" ) ) {
// no Device-URL for the user availabe, but plugin is enabled --> write info to Logger
logger("WARN: windowsphonepush is enable for user " . $rr['uid'] . ", but no Device-URL is specified for the user.");
} else {
// retrieve the number of unseen items and the id of the latest one (if there are more than
// one new entries since last poller run, only the latest one will be pushed)
$count = q("SELECT count(`id`) as count, max(`id`) as max FROM `item` WHERE `unseen` = 1 AND `uid` = %d",
intval($rr['uid'])
);
// send number of unseen items to the device (the number will be displayed on Start screen until
// App will be started by user) - this update will be sent every 10 minutes to update the number to 0 if
// user has loaded the timeline through app or website
$res_tile = send_tile_update($device_url, "", $count[0]['count'], "");
switch (trim($res_tile)) {
case "Received":
// ok, count has been pushed
break;
case "QueueFull":
// maximum of 30 messages reached, server rejects any further push notification until device reconnects
logger("INFO: Device-URL '" . $device_url . "' returns a QueueFull.");
break;
case "Suppressed":
// notification received and dropped as something in app was not enabled
logger("WARN. Device-URL '" . $device_url . "' returns a Suppressed. Unexpected error in Mobile App?");
break;
case "Dropped":
// mostly combines with Expired, in that case Device-URL will be deleted from pconfig (function send_push)
break;
default:
// error, mostly called by "" which means that the url (not "" which has been checked)
// didn't not received Microsoft Notification Server -> wrong url
logger("ERROR: specified Device-URL '" . $device_url . "' didn't produced any response.");
}
// additionally user receives the text of the newest item (function checks against last successfully pushed item)
if (intval($count[0]['max']) > intval($lastpushid)) {
// user can define if he wants to see the text of the item in the push notification
// this has been implemented as the device_url is not a https uri (not so secure)
$senditemtext = get_pconfig($rr['uid'], 'windowsphonepush', 'senditemtext');
if ($senditemtext == 1) {
// load item with the max id
$item = q("SELECT `author-name` as author, `body` as body FROM `item` where `id` = %d",
intval($count[0]['max'])
);
// as user allows to send the item, we want to show the sender of the item in the toast
// toasts are limited to one line, therefore place is limited - author shall be in
// max. 15 chars (incl. dots); author is displayed in bold font
$author = $item[0]['author'];
$author = ((strlen($author) > 12) ? substr($author, 0, 12) . "..." : $author);
// normally we show the body of the item, however if it is an url or an image we cannot
// show this in the toast (only test), therefore changing to an alternate text
// Otherwise BBcode-Tags will be eliminated and plain text cutted to 140 chars (incl. dots)
// BTW: information only possible in English
$body = $item[0]['body'];
if (substr($body, 0, 4) == "[url")
$body = "URL/Image ...";
else {
require_once('include/bbcode.php');
require_once("include/html2plain.php");
$body = bbcode($body, false, false, 2, true);
$body = html2plain($body, 0);
$body = ((strlen($body) > 137) ? substr($body, 0, 137) . "..." : $body);
}
} else {
// if user wishes higher privacy, we only display "Friendica - New timeline entry arrived"
$author = "Friendica";
$body = "New timeline entry arrived ...";
}
// only if toast push notification returns the Notification status "Received" we will update th settings with the
// new indicator max-id is checked against (QueueFull, Suppressed, N/A, Dropped shall qualify to resend
// the push notification some minutes later (BTW: if resulting in Expired for subscription status the
// device_url will be deleted (no further try on this url, see send_push)
// further log information done on count pushing with send_tile (see above)
$res_toast = send_toast($device_url, $author, $body);
if (trim($res_toast) === 'Received') {
set_pconfig($rr['uid'], 'windowsphonepush', 'lastpushid', $count[0]['max']);
}
}
}
}
}
}
/*
*
* Tile push notification change the number in the icon of the App in Start Screen of
* a Windows Phone Device, Image could be changed, not used for App "Friendica Mobile"
*
*/
function send_tile_update($device_url, $image_url, $count, $title, $priority = 1) {
$msg = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" .
"<wp:Notification xmlns:wp=\"WPNotification\">" .
"<wp:Tile>".
"<wp:BackgroundImage>" . $image_url . "</wp:BackgroundImage>" .
"<wp:Count>" . $count . "</wp:Count>" .
"<wp:Title>" . $title . "</wp:Title>" .
"</wp:Tile> " .
"</wp:Notification>";
$result = send_push($device_url, array(
'X-WindowsPhone-Target: token',
'X-NotificationClass: ' . $priority,
), $msg);
return $result;
}
/*
*
* Toast push notification send information to the top of the display
* if the user is not currently using the Friendica Mobile App, however
* there is only one line for displaying the information
*
*/
function send_toast($device_url, $title, $message, $priority = 2) {
$msg = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" .
"<wp:Notification xmlns:wp=\"WPNotification\">" .
"<wp:Toast>" .
"<wp:Text1>" . $title . "</wp:Text1>" .
"<wp:Text2>" . $message . "</wp:Text2>" .
"<wp:Param></wp:Param>" .
"</wp:Toast>" .
"</wp:Notification>";
$result = send_push($device_url, array(
'X-WindowsPhone-Target: toast',
'X-NotificationClass: ' . $priority,
), $msg);
return $result;
}
/*
*
* General function to send the push notification via cURL
*
*/
function send_push($device_url, $headers, $msg) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $device_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER,
$headers + array(
'Content-Type: text/xml',
'charset=utf-8',
'Accept: application/*',
)
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $msg);
$output = curl_exec($ch);
curl_close($ch);
// if we received "Expired" from Novartis server we will delete the obsolete device-URL
// and log this fact
$subscriptionStatus = get_header_value($output, 'X-SubscriptionStatus');
if ($subscriptionStatus == "Expired") {
set_pconfig(local_user(),'windowsphonepush','device_url', "");
logger("ERROR: the stored Device-URL " . $device_url . "returned an 'Expired' error, it has been deleted now.");
}
// the notification status shall be returned to windowsphonepush_cron (will
// update settings if 'Received' otherwise keep old value in settings (on QueuedFull. Suppressed, N/A, Dropped)
$notificationStatus = get_header_value($output, 'X-NotificationStatus');
return $notificationStatus;
}
/*
* helper function to receive statuses from webresponse of Microsoft server
*/
function get_header_value($content, $header) {
return preg_match_all("/$header: (.*)/i", $content, $match) ? $match[1][0] : "";
}
/*
*
* reading information from url and deciding which function to start
* show_settings = delivering settings to check
* update_settings = set the device_url
*
*/
function windowsphonepush_content(&$a) {
// Login with the specified Network credentials (like in api.php)
windowsphonepush_login();
$path = $a->argv[0];
$path2 = $a->argv[1];
if ($path == "windowsphonepush") {
switch ($path2) {
case "show_settings":
windowsphonepush_showsettings(&$a);
killme();
break;
case "update_settings":
$ret = windowsphonepush_updatesettings(&$a);
header("Content-Type: application/json; charset=utf-8");
echo json_encode(array('status' => $ret));
killme();
break;
default:
echo "Fehler";
}
}
}
/*
* return settings for windowsphonepush addon to be able to check them in WP app
*/
function windowsphonepush_showsettings(&$a) {
if(! local_user())
return;
$enable = get_pconfig(local_user(), 'windowsphonepush', 'enable');
$device_url = get_pconfig(local_user(), 'windowsphonepush', 'device_url');
$senditemtext = get_pconfig(local_user(), 'windowsphonepush', 'senditemtext');
$lastpushid = get_pconfig(local_user(), 'windowsphonepush', 'lastpushid');
if (!$device_url)
$device_url = "";
if (!$lastpushid)
$lastpushid = 0;
header ("Content-Type: application/json");
echo json_encode(array('uid' => local_user(),
'enable' => $enable,
'device_url' => $device_url,
'senditemtext' => $senditemtext,
'lastpushid' => $lastpushid));
}
/*
* update_settings is used to transfer the device_url from WP device to the Friendica server
* return the status of the operation to the server
*/
function windowsphonepush_updatesettings(&$a) {
if(! local_user()) {
return "Not Authenticated";
}
// no updating if user hasn't enabled the plugin
$enable = get_pconfig(local_user(), 'windowsphonepush', 'enable');
if(! $enable) {
return "Plug-in not enabled";
}
// check if sent url is empty - don't save and send return code to app
$device_url = $_POST['deviceurl'];
if ($device_url == "") {
logger("ERROR: no valid Device-URL specified - client transferred '" . $device_url . "'");
return "No valid Device-URL specified";
}
// check if sent url is already stored in database for another user, we assume that there was a change of
// the user on the Windows Phone device and that device url is no longer true for the other user, so we
// et the device_url for the OTHER user blank (should normally not occur as App should include User/server
// in url request to Microsoft Push Notification server)
$r = q("SELECT * FROM `pconfig` WHERE `uid` <> " . local_user() . " AND
`cat` = 'windowsphonepush' AND
`k` = 'device_url' AND
`v` = '" . $device_url . "'");
if(count($r)) {
foreach($r as $rr) {
set_pconfig($rr['uid'], 'windowsphonepush', 'device_url', '');
logger("WARN: the sent URL was already registered with user '" . $rr['uid'] . "'. Deleted for this user as we expect to be correct now for user '" . local_user() . "'.");
}
}
set_pconfig(local_user(),'windowsphonepush','device_url', $device_url);
// output the successfull update of the device URL to the logger for error analysis if necessary
logger("INFO: Device-URL for user '" . local_user() . "' has been updated with '" . $device_url . "'");
return "Device-URL updated successfully!";
}
/*
* helper function to login to the server with the specified Network credentials
* (mainly copied from api.php)
*/
function windowsphonepush_login() {
if (!isset($_SERVER['PHP_AUTH_USER'])) {
logger('API_login: ' . print_r($_SERVER, true), LOGGER_DEBUG);
header('WWW-Authenticate: Basic realm="Friendica"');
header('HTTP/1.0 401 Unauthorized');
die('This api requires login');
}
$user = $_SERVER['PHP_AUTH_USER'];
$encrypted = hash('whirlpool',trim($_SERVER['PHP_AUTH_PW']));
// check if user specified by app is available in the user table
$r = q("SELECT * FROM `user` WHERE ( `email` = '%s' OR `nickname` = '%s' )
AND `password` = '%s' AND `blocked` = 0 AND `account_expired` = 0 AND `account_removed` = 0 AND `verified` = 1 LIMIT 1",
dbesc(trim($user)),
dbesc(trim($user)),
dbesc($encrypted)
);
if(count($r)){
$record = $r[0];
} else {
logger('API_login failure: ' . print_r($_SERVER,true), LOGGER_DEBUG);
header('WWW-Authenticate: Basic realm="Friendica"');
header('HTTP/1.0 401 Unauthorized');
die('This api requires login');
}
require_once('include/security.php');
authenticate_success($record); $_SESSION["allow_api"] = true;
call_hooks('logged_in', $a->user);
}