diff --git a/include/delivery.php b/include/delivery.php
index cdd59451f..dc02faaba 100644
--- a/include/delivery.php
+++ b/include/delivery.php
@@ -2,6 +2,7 @@
require_once("boot.php");
require_once('include/queue_fn.php');
require_once('include/html2plain.php');
+require_once("include/ostatus.php");
function delivery_run(&$argv, &$argc){
global $a, $db;
@@ -391,7 +392,8 @@ function delivery_run(&$argv, &$argc){
continue;
if(($top_level) && ($public_message) && ($item['author-link'] === $item['owner-link']) && (! $expire))
- $slaps[] = atom_entry($item,'html',null,$owner,true);
+ $slaps[] = ostatus_salmon($item,$owner);
+ //$slaps[] = atom_entry($item,'html',null,$owner,true);
}
logger('notifier: slapdelivery: ' . $contact['name']);
diff --git a/include/items.php b/include/items.php
index c4310c24e..53f4784c2 100644
--- a/include/items.php
+++ b/include/items.php
@@ -4479,7 +4479,8 @@ function atom_entry($item,$type,$author,$owner,$comment = false,$cid = 0) {
//$o .= "\t".''."\r\n";
//$o .= "\t".''."\r\n";
- $o .= item_get_attachment($item);
+ // Deactivated since it was meant only for OStatus
+ //$o .= item_get_attachment($item);
$o .= item_getfeedattach($item);
diff --git a/include/notifier.php b/include/notifier.php
index 9dac5f114..ec2b666be 100644
--- a/include/notifier.php
+++ b/include/notifier.php
@@ -4,6 +4,7 @@ require_once('include/queue_fn.php');
require_once('include/html2plain.php');
require_once("include/Scrape.php");
require_once('include/diaspora.php');
+require_once("include/ostatus.php");
/*
* This file was at one time responsible for doing all deliveries, but this caused
@@ -529,7 +530,8 @@ function notifier_run(&$argv, &$argc){
unset($photos);
} else {
- $slap = atom_entry($target_item,'html',null,$owner,false);
+ $slap = ostatus_salmon($target_item,$owner);
+ //$slap = atom_entry($target_item,'html',null,$owner,false);
if($followup) {
foreach($items as $item) { // there is only one item
@@ -569,7 +571,8 @@ function notifier_run(&$argv, &$argc){
$atom .= atom_entry($item,'text',null,$owner,true);
if(($top_level) && ($public_message) && ($item['author-link'] === $item['owner-link']) && (! $expire))
- $slaps[] = atom_entry($item,'html',null,$owner,true);
+ $slaps[] = ostatus_salmon($item,$owner);
+ //$slaps[] = atom_entry($item,'html',null,$owner,true);
}
}
}
diff --git a/include/ostatus.php b/include/ostatus.php
index 523ccfe51..ce254ed61 100644
--- a/include/ostatus.php
+++ b/include/ostatus.php
@@ -14,6 +14,15 @@ define('OSTATUS_DEFAULT_POLL_INTERVAL', 30); // given in minutes
define('OSTATUS_DEFAULT_POLL_TIMEFRAME', 1440); // given in minutes
define('OSTATUS_DEFAULT_POLL_TIMEFRAME_MENTIONS', 14400); // given in minutes
+define("NS_ATOM", "http://www.w3.org/2005/Atom");
+define("NS_THR", "http://purl.org/syndication/thread/1.0");
+define("NS_GEORSS", "http://www.georss.org/georss");
+define("NS_ACTIVITY", "http://activitystrea.ms/spec/1.0/");
+define("NS_MEDIA", "http://purl.org/syndication/atommedia");
+define("NS_POCO", "http://portablecontacts.net/spec/1.0");
+define("NS_OSTATUS", "http://ostatus.org/schema/1.0");
+define("NS_STATUSNET", "http://status.net/schema/api/1/");
+
function ostatus_check_follow_friends() {
$r = q("SELECT `uid`,`v` FROM `pconfig` WHERE `cat`='system' AND `k`='ostatus_legacy_contact' AND `v` != ''");
@@ -1067,4 +1076,382 @@ function ostatus_store_conversation($itemid, $conversation_url) {
logger('Storing conversation url '.$conversation_url.' for id '.$itemid);
}
}
+
+function xml_add_element($doc, $parent, $element, $value = "", $attributes = array()) {
+ $element = $doc->createElement($element, xmlify($value));
+
+ foreach ($attributes AS $key => $value) {
+ $attribute = $doc->createAttribute($key);
+ $attribute->value = xmlify($value);
+ $element->appendChild($attribute);
+ }
+
+ $parent->appendChild($element);
+}
+
+function ostatus_add_header($doc, $owner) {
+ $a = get_app();
+
+ $r = q("SELECT * FROM `profile` WHERE `uid` = %d AND `is-default`",
+ intval($owner["uid"]));
+ if (!$r)
+ return;
+
+ $profile = $r[0];
+
+ $root = $doc->createElementNS(NS_ATOM, 'feed');
+ $doc->appendChild($root);
+
+ $root->setAttribute("xmlns:thr", NS_THR);
+ $root->setAttribute("xmlns:georss", NS_GEORSS);
+ $root->setAttribute("xmlns:activity", NS_ACTIVITY);
+ $root->setAttribute("xmlns:media", NS_MEDIA);
+ $root->setAttribute("xmlns:poco", NS_POCO);
+ $root->setAttribute("xmlns:ostatus", NS_OSTATUS);
+ $root->setAttribute("xmlns:statusnet", NS_STATUSNET);
+
+ $attributes = array("uri" => "https://friendi.ca", "version" => FRIENDICA_VERSION."-".DB_UPDATE_VERSION);
+ xml_add_element($doc, $root, "generator", FRIENDICA_PLATFORM, $attributes);
+ xml_add_element($doc, $root, "id", $a->get_baseurl()."/profile/".$owner["nick"]);
+ xml_add_element($doc, $root, "title", sprintf("%s timeline", $profile["name"]));
+ xml_add_element($doc, $root, "subtitle", sprintf("Updates from %s on %s", $profile["name"], $a->config["sitename"]));
+ xml_add_element($doc, $root, "logo", $profile["photo"]);
+ xml_add_element($doc, $root, "updated", datetime_convert("UTC", "UTC", "now", ATOM_TIME));
+
+ $author = ostatus_add_author($doc, $owner, $profile);
+ $root->appendChild($author);
+
+ $attributes = array("href" => $owner["url"], "rel" => "alternate", "type" => "text/html");
+ xml_add_element($doc, $root, "link", "", $attributes);
+
+ // To-Do: We have to find out what this is
+ //$attributes = array("href" => $a->get_baseurl()."/sup",
+ // "rel" => "http://api.friendfeed.com/2008/03#sup",
+ // "type" => "application/json");
+ //xml_add_element($doc, $root, "link", "", $attributes);
+
+ ostatus_hublinks($doc, $root);
+
+ $attributes = array("href" => $a->get_baseurl()."/salmon/".$owner["nick"], "rel" => "salmon");
+ xml_add_element($doc, $root, "link", "", $attributes);
+
+ $attributes = array("href" => $a->get_baseurl()."/salmon/".$owner["nick"], "rel" => "http://salmon-protocol.org/ns/salmon-replies");
+ xml_add_element($doc, $root, "link", "", $attributes);
+
+ $attributes = array("href" => $a->get_baseurl()."/salmon/".$owner["nick"], "rel" => "http://salmon-protocol.org/ns/salmon-mention");
+ xml_add_element($doc, $root, "link", "", $attributes);
+
+ $attributes = array("href" => $a->get_baseurl()."/api/statuses/user_timeline/".$owner["nick"].".atom",
+ "rel" => "self", "type" => "application/atom+xml");
+ xml_add_element($doc, $root, "link", "", $attributes);
+
+ return $root;
+}
+
+function ostatus_hublinks($doc, $root) {
+ $a = get_app();
+ $hub = get_config('system','huburl');
+
+ $hubxml = '';
+ if(strlen($hub)) {
+ $hubs = explode(',', $hub);
+ if(count($hubs)) {
+ foreach($hubs as $h) {
+ $h = trim($h);
+ if(! strlen($h))
+ continue;
+ if ($h === '[internal]')
+ $h = $a->get_baseurl() . '/pubsubhubbub';
+ xml_add_element($doc, $root, "link", "", array("href" => $h, "rel" => "hub"));
+ }
+ }
+ }
+}
+
+function ostatus_get_attachment($doc, $root, $item) {
+ $o = "";
+ $siteinfo = get_attached_data($item["body"]);
+
+ switch($siteinfo["type"]) {
+ case 'link':
+ $attributes = array("rel" => "enclosure",
+ "href" => $siteinfo["url"],
+ "type" => "text/html; charset=UTF-8",
+ "length" => "",
+ "title" => $siteinfo["title"]);
+ xml_add_element($doc, $root, "link", "", $attributes);
+ break;
+ case 'photo':
+ $imgdata = get_photo_info($siteinfo["image"]);
+ $attributes = array("rel" => "enclosure",
+ "href" => $siteinfo["image"],
+ "type" => $imgdata["mime"],
+ "length" => intval($imgdata["size"]));
+ xml_add_element($doc, $root, "link", "", $attributes);
+ break;
+ case 'video':
+ $attributes = array("rel" => "enclosure",
+ "href" => $siteinfo["url"],
+ "type" => "text/html; charset=UTF-8",
+ "length" => "",
+ "title" => $siteinfo["title"]);
+ xml_add_element($doc, $root, "link", "", $attributes);
+ break;
+ default:
+ break;
+ }
+
+ $arr = explode('[/attach],',$item['attach']);
+ if(count($arr)) {
+ foreach($arr as $r) {
+ $matches = false;
+ $cnt = preg_match('|\[attach\]href=\"(.*?)\" length=\"(.*?)\" type=\"(.*?)\" title=\"(.*?)\"|',$r,$matches);
+ if($cnt) {
+ $attributes = array("rel" => "enclosure",
+ "href" => $matches[1],
+ "type" => $matches[3]);
+
+ if(intval($matches[2]))
+ $attributes["length"] = intval($matches[2]);
+
+ if(trim($matches[4]) != "")
+ $attributes["title"] = trim($matches[4]);
+
+ xml_add_element($doc, $root, "link", "", $attributes);
+ }
+ }
+ }
+}
+
+function ostatus_add_author($doc, $owner, $profile) {
+ $a = get_app();
+
+ $author = $doc->createElement("author");
+ xml_add_element($doc, $author, "activity:object-type", ACTIVITY_OBJ_PERSON);
+ xml_add_element($doc, $author, "uri", $owner["url"]);
+ xml_add_element($doc, $author, "name", $owner["nick"]);
+
+ $attributes = array("rel" => "alternate", "type" => "text/html", "href" => $owner["url"]);
+ xml_add_element($doc, $author, "link", "", $attributes);
+
+ $attributes = array(
+ "rel" => "avatar",
+ "type" => "image/jpeg", // To-Do?
+ "media:width" => 175,
+ "media:height" => 175,
+ "href" => $profile["photo"]);
+ xml_add_element($doc, $author, "link", "", $attributes);
+
+ $attributes = array(
+ "rel" => "avatar",
+ "type" => "image/jpeg", // To-Do?
+ "media:width" => 80,
+ "media:height" => 80,
+ "href" => $profile["thumb"]);
+ xml_add_element($doc, $author, "link", "", $attributes);
+
+ xml_add_element($doc, $author, "poco:preferredUsername", $owner["nick"]);
+ xml_add_element($doc, $author, "poco:displayName", $profile["name"]);
+ xml_add_element($doc, $author, "poco:note", $profile["about"]);
+
+ if (trim($owner["location"]) != "") {
+ $element = $doc->createElement("poco:address");
+ xml_add_element($doc, $element, "poco:formatted", $owner["location"]);
+ $author->appendChild($element);
+ }
+
+ if (trim($profile["homepage"]) != "") {
+ $urls = $doc->createElement("poco:urls");
+ xml_add_element($doc, $urls, "poco:type", "homepage");
+ xml_add_element($doc, $urls, "poco:value", $profile["homepage"]);
+ xml_add_element($doc, $urls, "poco:primary", "true");
+ $author->appendChild($urls);
+ }
+
+ xml_add_element($doc, $author, "followers", "", array("url" => $a->get_baseurl()."/viewcontacts/".$owner["nick"]));
+ xml_add_element($doc, $author, "statusnet:profile_info", "", array("local_id" => $owner["uid"]));
+
+ return $author;
+}
+
+function ostatus_entry($doc, $item, $owner, $toplevel = false) {
+ $a = get_app();
+
+ if (!$toplevel) {
+ $entry = $doc->createElement("entry");
+ $title = sprintf("New note by %s", $owner["nick"]);
+ } else {
+ $entry = $doc->createElementNS(NS_ATOM, "entry");
+
+ $entry->setAttribute("xmlns:thr", NS_THR);
+ $entry->setAttribute("xmlns:georss", NS_GEORSS);
+ $entry->setAttribute("xmlns:activity", NS_ACTIVITY);
+ $entry->setAttribute("xmlns:media", NS_MEDIA);
+ $entry->setAttribute("xmlns:poco", NS_POCO);
+ $entry->setAttribute("xmlns:ostatus", NS_OSTATUS);
+ $entry->setAttribute("xmlns:statusnet", NS_STATUSNET);
+
+ $r = q("SELECT * FROM `profile` WHERE `uid` = %d AND `is-default`",
+ intval($owner["uid"]));
+ if (!$r)
+ return;
+
+ $profile = $r[0];
+
+ $author = ostatus_add_author($doc, $owner, $profile);
+ $entry->appendChild($author);
+
+ $title = sprintf("New comment by %s", $owner["nick"]);
+ }
+
+ // To use the object-type "bookmark" we have to implement these elements:
+ //
+ //