Skip to content
This repository has been archived by the owner on Nov 25, 2020. It is now read-only.

Commit

Permalink
Big update of the Etherpad-lite integration.
Browse files Browse the repository at this point in the history
Seems like we cannot detect pads with no author, we would have to set up a task to clean orphan pads.
Should Fix #865 Fix #867
  • Loading branch information
cdujeu committed Mar 19, 2015
1 parent 73ca9a7 commit 6da3a28
Show file tree
Hide file tree
Showing 9 changed files with 199 additions and 155 deletions.
147 changes: 90 additions & 57 deletions core/src/plugins/editor.etherpad/class.EtherpadClient.php
Expand Up @@ -31,69 +31,70 @@ public function switchAction($actionName, $httpVars, $fileVars)
$this->baseURL = rtrim($this->getFilteredOption("ETHERPAD_SERVER"), "/");
$this->apiKey = $this->getFilteredOption("ETHERPAD_APIKEY");

if (isSet($httpVars["file"])) {

$repository = ConfService::getRepository();
if (!$repository->detectStreamWrapper(false)) {
return false;
}
$plugin = AJXP_PluginsService::findPlugin("access", $repository->getAccessType());
$streamData = $plugin->detectStreamWrapper(true);
$destStreamURL = $streamData["protocol"]."://".$repository->getId()."/";
$filename = $destStreamURL. AJXP_Utils::securePath($httpVars["file"]);

if (!is_file($filename)) {
throw new Exception("Cannot find file!");
$userSelection = new UserSelection(ConfService::getRepository(), $httpVars);
if ($userSelection->isEmpty()){
throw new Exception("Empty selection");
}
$repository = ConfService::getRepository();
if (!$repository->detectStreamWrapper(false)) {
return false;
}
$plugin = AJXP_PluginsService::findPlugin("access", $repository->getAccessType());
$selectedNode = $userSelection->getUniqueNode($plugin);
$selectedNode->loadNodeInfo();
if(!$selectedNode->isLeaf()){
throw new Exception("Cannot handle folders, please select a file!");
}
$nodeExtension = strtolower(pathinfo($selectedNode->getPath(), PATHINFO_EXTENSION));

// Determine pad ID
if($nodeExtension == "pad"){
$padID = file_get_contents($selectedNode->getUrl());
}else{
// TRY TO LOAD PAD ID FROM NODE SHARED METADATA
$metadata = $selectedNode->retrieveMetadata("etherpad", AJXP_METADATA_ALLUSERS, AJXP_METADATA_SCOPE_GLOBAL, false);
if(isSet($metadata["pad_id"])){
$padID = $metadata["pad_id"];
}else{
$padID = AJXP_Utils::generateRandomString();
$selectedNode->setMetadata("etherpad", array("pad_id" => $padID), AJXP_METADATA_ALLUSERS, AJXP_METADATA_SCOPE_GLOBAL, false);
}
}

require_once("etherpad-client/etherpad-lite-client.php");
$client = new EtherpadLiteClient($this->apiKey,$this->baseURL."/api");
$userName = AuthService::getLoggedUser()->getId();
$res = $client->createAuthorIfNotExistsFor($userName, $userName);
$loggedUser = AuthService::getLoggedUser();
$userName = $loggedUser->getId();
$userLabel = $loggedUser->mergedRole->filterParameterValue("core.conf", "USER_DISPLAY_NAME", AJXP_REPO_SCOPE_ALL, $userName);
$res = $client->createAuthorIfNotExistsFor($userName, $userLabel);
$authorID = $res->authorID;
$res2 = $client->createGroupIfNotExistsFor("ajaxplorer");
$res2 = $client->createGroupIfNotExistsFor($loggedUser->getGroupPath());
$groupID = $res2->groupID;
$fullId = $groupID."$".$padID;

if ($actionName == "etherpad_create") {

if (isSet($httpVars["pad_name"])) {

$padID = $httpVars["pad_name"];
$startContent = "";
if ($httpVars["pad_type"] && $httpVars["pad_type"] == 'free') {
$padID = "FREEPAD__".$padID;
}

} else if (isSet($httpVars["file"])) {

$startContent = file_get_contents($filename);
if (strtolower(pathinfo($filename, PATHINFO_EXTENSION)) == "html") {
$startContentHTML = $startContent;
}
$padID = AJXP_Utils::slugify($httpVars["file"]);
$resP = $client->listPads($groupID);

$currentContent = file_get_contents($selectedNode->getUrl());
if($nodeExtension == "html" && strpos($currentContent, "<html>") === false){
$currentContent = "<html><head></head><body>$currentContent</body></html>";
}


$resP = $client->listPads($res2->groupID);

$pads = $resP->padIDs;
if (!in_array($groupID.'$'.$padID, $pads)) {
$res3 = $client->createGroupPad($groupID, $padID, null);
if (isSet($startContentHTML)) {
$client->setHTML($groupID.'$'.$padID, $startContentHTML);
} else if (!empty($startContent)) {
$client->setText($groupID.'$'.$padID, $startContent);
if (!in_array($fullId, $resP->padIDs)) {
$client->createGroupPad($groupID, $padID, null);
if($nodeExtension == "html" && !empty($currentContent)){
$client->setHTML($fullId, $currentContent);
}else if($nodeExtension != "pad"){
$client->setText($fullId, $currentContent);
}
} else {
// Check if content needs relaunch!
$test = $client->getText($groupID.'$'.$padID);
if (!empty($startContent) && $test->text != $startContent) {
if (isSet($startContentHTML)) {
$client->setHTML($groupID.'$'.$padID, $startContentHTML);
} else {
$client->setText($groupID.'$'.$padID, $startContent);
} else if($nodeExtension != "pad") {
// If someone is already connected, do not override.
$existingAuthors = $client->listAuthorsOfPad($fullId);
if(!count($existingAuthors->authorIDs)){
if($nodeExtension == "html" && !empty($currentContent)){
$client->setHTML($fullId, $currentContent);
}else{
$client->setText($fullId, $currentContent);
}
}
}
Expand All @@ -116,22 +117,39 @@ public function switchAction($actionName, $httpVars, $fileVars)

} else if ($actionName == "etherpad_save") {

$node = new AJXP_Node($filename);

$padID = $httpVars["pad_id"];
if (isSet($startContentHTML)) {

if ($nodeExtension == "html" || $nodeExtension == "pad") {
$res = $client->getHTML($padID);
$content = $res->html;
} else {
$res = $client->getText($padID);
$content = $res->text;
}

if($nodeExtension == "pad"){
// Create a new file and save the content in it.
$origUrl = $selectedNode->getUrl();
$mess = ConfService::getMessages();
$dateStamp = date(" Y-m-d H:i", time());
$startUrl = preg_replace('"\.pad$"', $dateStamp.'.html', $origUrl);
$newNode = new AJXP_Node($startUrl);
AJXP_Controller::applyHook("node.before_create", array($newNode, strlen($content)));
file_put_contents($newNode->getUrl(), $content);
AJXP_Controller::applyHook("node.change", array(null, $newNode));
}else{
AJXP_Controller::applyHook("node.before_change", array($selectedNode, strlen($content)));
file_put_contents($selectedNode->getUrl(), $content);
clearstatcache(true, $selectedNode->getUrl());
$selectedNode->loadNodeInfo(true);
AJXP_Controller::applyHook("node.change", array($selectedNode, $selectedNode));
}

AJXP_Controller::applyHook("node.before_change", array($node, strlen($res->text)));
file_put_contents($filename, $res->text);
AJXP_Controller::applyHook("node.change", array($node, $node));

} else if ($actionName == "etherpad_close") {

// WE SHOULD DETECT IF THERE IS NOBODY CONNECTED ANYMORE, AND DELETE THE PAD.
// BUT SEEMS LIKE THERE'S NO WAY TO PROPERLY REMOVE AN AUTHOR VIA API
$sessionID = $httpVars["session_id"];
$client->deleteSession($sessionID);

Expand All @@ -145,9 +163,24 @@ public function switchAction($actionName, $httpVars, $fileVars)
HTMLWriter::charsetHeader("application/json");
echo(json_encode($res));

} else if ($actionName == "etherpad_get_content"){

HTMLWriter::charsetHeader("text/plain");
echo $client->getText($httpVars["pad_id"])->text;

}

}
return null;

}

/**
* @param AJXP_Node $ajxpNode
*/
public function hideExtension(&$ajxpNode){
if(strtolower(pathinfo($ajxpNode->getPath(), PATHINFO_EXTENSION)) == "pad"){
$baseName = AJXP_Utils::safeBasename($ajxpNode->getPath());
$ajxpNode->setLabel(str_replace(".pad", "", $baseName));
}
}
}
115 changes: 44 additions & 71 deletions core/src/plugins/editor.etherpad/class.EtherpadLauncher.js
Expand Up @@ -28,8 +28,9 @@ Class.create("EtherpadLauncher", AbstractEditor, {
$super(oFormObject, options);
if(!ajaxplorer.user || ajaxplorer.user.canWrite()){
this.canWrite = true;
this.actions.get("saveButton").observe('click', function(){
this.saveFile();
this.actions.get("saveButton").observe('click', function(e){
Event.stop(e);
this.saveFile();
return false;
}.bind(this));
}else{
Expand All @@ -38,6 +39,7 @@ Class.create("EtherpadLauncher", AbstractEditor, {
}
if(options.context.__className == "Modal"){
this.actions.get("downloadFileButton").observe('click', function(){
Event.stop(e);
if(!this.currentFile) return false;
ajaxplorer.triggerDownload(ajxpBootstrap.parameters.get('ajxpServerAccess')+'&action=download&file='+this.currentFile);
return false;
Expand All @@ -47,82 +49,29 @@ Class.create("EtherpadLauncher", AbstractEditor, {
}
},

initEmptyPadPane : function(form){

var selector = form.down('[name="pad_list"]');
var textInput = form.down('[name="new_pad_name"]');
var joinButton = form.down('#join_pad');
fitHeightToBottom(form.down("#ether_frame"), null, null, true);

var con = new Connexion();
con.setParameters(new Hash({
get_action: 'etherpad_proxy_api',
api_action: 'list_pads'
}));
con.onComplete = function(transport){
var pads = $A(transport.responseJSON.padIDs);
var frees = $A();
var files = $A();
pads.each(function(el){
var label = el.split('$').pop();
if(label.startsWith('FREEPAD__')){
frees.push(label);
}else{
files.push(label);
}
});
selector.insert(new Element('optgroup',{label:MessageHash['etherpad.5']}));
frees.each(function(e){
selector.insert(new Element('option', {value:e}).update(e.replace('FREEPAD__', '')));
});
selector.insert(new Element('option', {value:-1}).update(MessageHash['etherpad.9']));

if(files.size()){
selector.insert(new Element('optgroup', {label:MessageHash['etherpad.6']}));
files.each(function(e){
selector.insert(new Element('option', {value:e}).update(e));
});
}

selector.observe("change", function(){
textInput[(selector.getValue() == -1)?'show':'hide']();
});
textInput[(selector.getValue() == -1)?'show':'hide']();
};
con.sendAsync();

joinButton.observe("click", function(){

var conn = new Connexion();
conn.addParameter("get_action", "etherpad_create");
if(selector.getValue() == -1){
conn.addParameter("pad_name", textInput.getValue());
conn.addParameter("pad_type", 'free');
}else{
conn.addParameter("pad_name", selector.getValue());
}
conn.onComplete = function(transport){
var data = transport.responseJSON;
$("etherpad_container").down("#ether_frame").src = data.url;
};
conn.sendAsync();
});

},

open : function($super, nodeOrNodes){
$super(nodeOrNodes);
this.node = nodeOrNodes;
var frame = this.element.down('#ether_box_frame');
var fileName = nodeOrNodes.getPath();
var conn = new Connexion();
var extension = getFileExtension(fileName);
if(extension == "pad"){
// Replace 'Save' by 'Export'
this.actions.get("saveButton").down(".actionbar_button_label").update(MessageHash['etherpad.10']);
}
conn.addParameter("get_action", "etherpad_create");
conn.addParameter("file", fileName);
conn.onComplete = function(transport){
var data = transport.responseJSON;
this.padID = data.padID;
this.sessionID = data.sessionID;
$("ether_box").down("#ether_box_frame").src = data.url;
fitHeightToBottom($("ether_box").down("#ether_box_frame"));
console.log(data.url + '?format=text');
frame.src = data.url;
fitHeightToBottom(frame, null, 25);
if(extension != "pad"){
this.pe = new PeriodicalExecuter(this.observeChanges.bind(this), 5);
}
}.bind(this);
conn.sendAsync();

Expand All @@ -132,13 +81,13 @@ Class.create("EtherpadLauncher", AbstractEditor, {
}

this.element.observe("editor:enterFSend", function(){
fitHeightToBottom($("ether_box").down("#ether_box_frame"));
fitHeightToBottom(frame, null, 25);
});
this.element.observe("editor:resize", function(){
fitHeightToBottom($("ether_box").down("#ether_box_frame"));
fitHeightToBottom(frame, null, 25);
});
this.element.observe("editor:exitFSend", function(){
fitHeightToBottom($("ether_box").down("#ether_box_frame"));
fitHeightToBottom(frame, null, 25);
});

this.element.observeOnce("editor:close", function(){
Expand All @@ -148,7 +97,12 @@ Class.create("EtherpadLauncher", AbstractEditor, {
conn.addParameter("pad_id", this.padID);
conn.addParameter("session_id", this.sessionID);
conn.sendAsync();
if(this.pe){
this.pe.stop();
}
}.bind(this));

this.updateTitle(getBaseName(fileName));
},


Expand All @@ -159,6 +113,25 @@ Class.create("EtherpadLauncher", AbstractEditor, {
conn.addParameter("file", this.node.getPath());
conn.addParameter("pad_id", this.padID);
conn.sendAsync();
}
this.setModified(false);
},

observeChanges: function(){
if(!this.padID || !this.node) return;
var conn = new Connexion();
conn.discrete = true;
conn.onComplete = function(transport){
var content = transport.responseText;
if(this.previousContent && this.previousContent != content){
this.setModified(true);
}
this.previousContent = content;
}.bind(this);
conn.addParameter("get_action", "etherpad_get_content");
conn.addParameter("file", this.node.getPath());
conn.addParameter("pad_id", this.padID);
conn.sendAsync();

}

});
Binary file added core/src/plugins/editor.etherpad/discussion.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion core/src/plugins/editor.etherpad/i18n/de.php
Expand Up @@ -29,5 +29,6 @@
"6" => "Dateien",
"7" => "Beitreten",
"8" => "Board name",
"9" => "Neues Board erstellen",
"9" => "You can also create <a>new discussion board</a>",
"10" => "Export"
);
3 changes: 2 additions & 1 deletion core/src/plugins/editor.etherpad/i18n/en.php
Expand Up @@ -29,5 +29,6 @@
"6" => "Files",
"7" => "Join",
"8" => "Board name",
"9" => "Create new board",
"9" => "You can also create <a>new discussion board</a>",
"10" => "Export"
);
3 changes: 2 additions & 1 deletion core/src/plugins/editor.etherpad/i18n/fr.php
Expand Up @@ -29,5 +29,6 @@
"6" => "Fichiers",
"7" => "Rejoindre",
"8" => "Nom de l'adroise",
"9" => "Créer une nouvelle ardoise",
"9" => "Vous pouvez aussi <a>créer une nouvelle ardoise de discussion</a>",
"10" => "Exporter"
);
3 changes: 2 additions & 1 deletion core/src/plugins/editor.etherpad/i18n/it.php
Expand Up @@ -29,5 +29,6 @@
"6" => "File",
"7" => "Entra",
"8" => "Nome Sessione",
"9" => "Crea Nuova Sessione",
"9" => "You can also create <a>new discussion board</a>",
"10" => "Export"
);

5 comments on commit 6da3a28

@Nanomani
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the menu never appears since this update. There is a new way to launch Etherpad ?

2015-03-20_195901

@Nanomani
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Up :-)

@cdujeu
Copy link
Member Author

@cdujeu cdujeu commented on 6da3a28 Mar 30, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes
Create >>> "Create New discussion Pad" :-)

@Nanomani
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Arf... Sorry again. I m completely lost.

"Ardoise de collaboration" is not displayed now. If you prefere I have this :

2015-03-30_140409

I found no option in the settings for "Create" >>> "Create New discussion Pad"

perhaps I have to make an appointment with a ophtalmo ?

@Nanomani
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok I found... :-)

Please sign in to comment.