Import works now on the server side
parent
4b268f9579
commit
b13fbbfd73
|
@ -0,0 +1,117 @@
|
|||
/**
|
||||
* Handles the import requests
|
||||
*/
|
||||
|
||||
/*
|
||||
* 2011 Peter 'Pita' Martischka
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
var padManager = require("./PadManager");
|
||||
var padMessageHandler = require("./PadMessageHandler");
|
||||
var async = require("async");
|
||||
var fs = require("fs");
|
||||
var settings = require('./settings');
|
||||
var formidable = require('formidable');
|
||||
|
||||
//load abiword only if its enabled
|
||||
if(settings.abiword != null)
|
||||
var abiword = require("./Abiword");
|
||||
|
||||
/**
|
||||
* do a requested import
|
||||
*/
|
||||
exports.doImport = function(req, res, padId)
|
||||
{
|
||||
//pipe to a file
|
||||
//convert file to text via abiword
|
||||
//set text in the pad
|
||||
|
||||
var srcFile, destFile;
|
||||
var pad;
|
||||
var text;
|
||||
|
||||
async.series([
|
||||
//save the uploaded file to /tmp
|
||||
function(callback)
|
||||
{
|
||||
var form = new formidable.IncomingForm();
|
||||
form.keepExtensions = true;
|
||||
|
||||
form.parse(req, function(err, fields, files)
|
||||
{
|
||||
//save the path of the uploaded file
|
||||
srcFile = files.file.path;
|
||||
|
||||
callback(err);
|
||||
});
|
||||
},
|
||||
|
||||
//convert file to text
|
||||
function(callback)
|
||||
{
|
||||
var randNum = Math.floor(Math.random()*new Date().getTime());
|
||||
destFile = "/tmp/eplite_import_" + randNum + ".txt";
|
||||
abiword.convertFile(srcFile, destFile, "txt", callback);
|
||||
},
|
||||
|
||||
//get the pad object
|
||||
function(callback)
|
||||
{
|
||||
padManager.getPad(padId, function(err, _pad)
|
||||
{
|
||||
pad = _pad;
|
||||
callback(err);
|
||||
});
|
||||
},
|
||||
|
||||
//read the text
|
||||
function(callback)
|
||||
{
|
||||
fs.readFile(destFile, "utf8", function(err, _text)
|
||||
{
|
||||
text = _text;
|
||||
callback(err);
|
||||
});
|
||||
},
|
||||
|
||||
//change text of the pad and broadcast the changeset
|
||||
function(callback)
|
||||
{
|
||||
pad.setText(text);
|
||||
padMessageHandler.updatePadClients(pad, callback);
|
||||
},
|
||||
|
||||
//clean up temporary files
|
||||
function(callback)
|
||||
{
|
||||
async.parallel([
|
||||
function(callback)
|
||||
{
|
||||
fs.unlink(srcFile, callback);
|
||||
},
|
||||
function(callback)
|
||||
{
|
||||
fs.unlink(destFile, callback);
|
||||
}
|
||||
], callback);
|
||||
}
|
||||
], function(err)
|
||||
{
|
||||
//close the connection
|
||||
res.send("ok");
|
||||
|
||||
if(err) throw err;
|
||||
});
|
||||
}
|
|
@ -191,6 +191,20 @@ Class('Pad', {
|
|||
return this.atext.text;
|
||||
},
|
||||
|
||||
setText : function(newText)
|
||||
{
|
||||
//clean the new text
|
||||
newText = exports.cleanText(newText);
|
||||
|
||||
var oldText = this.text();
|
||||
|
||||
//create the changeset
|
||||
var changeset = Changeset.makeSplice(oldText, 0, oldText.length-1, newText);
|
||||
|
||||
//append the changeset
|
||||
this.appendRevision(changeset);
|
||||
},
|
||||
|
||||
appendChatMessage: function(text, userId, time)
|
||||
{
|
||||
this.chatHead++;
|
||||
|
|
|
@ -433,8 +433,16 @@ function handleUserChanges(client, message)
|
|||
pad.appendRevision(nlChangeset);
|
||||
}
|
||||
|
||||
//ex. updatePadClients
|
||||
exports.updatePadClients(pad, callback);
|
||||
}
|
||||
], function(err)
|
||||
{
|
||||
if(err) throw err;
|
||||
});
|
||||
}
|
||||
|
||||
exports.updatePadClients = function(pad, callback)
|
||||
{
|
||||
//go trough all sessions on this pad
|
||||
async.forEach(pad2sessions[pad.id], function(session, callback)
|
||||
{
|
||||
|
@ -498,11 +506,6 @@ function handleUserChanges(client, message)
|
|||
|
||||
sessioninfos[session].rev = pad.getHeadRevisionNumber();
|
||||
},callback);
|
||||
}
|
||||
], function(err)
|
||||
{
|
||||
if(err) throw err;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -32,6 +32,7 @@ var express = require('express');
|
|||
var path = require('path');
|
||||
var minify = require('./minify');
|
||||
var exportHandler;
|
||||
var importHandler;
|
||||
var exporthtml;
|
||||
var readOnlyManager;
|
||||
|
||||
|
@ -51,7 +52,7 @@ catch(e)
|
|||
|
||||
var serverName = "Etherpad-Lite " + version + " (http://j.mp/ep-lite)";
|
||||
|
||||
//cache a week
|
||||
//cache 6 hours
|
||||
exports.maxAge = 1000*60*60*6;
|
||||
|
||||
async.waterfall([
|
||||
|
@ -70,6 +71,7 @@ async.waterfall([
|
|||
readOnlyManager = require("./ReadOnlyManager");
|
||||
exporthtml = require("./exporters/exporthtml");
|
||||
exportHandler = require('./ExportHandler');
|
||||
importHandler = require('./ImportHandler');
|
||||
|
||||
//set logging
|
||||
if(settings.logHTTP)
|
||||
|
@ -215,6 +217,20 @@ async.waterfall([
|
|||
exportHandler.doExport(req, res, req.params.pad, req.params.type);
|
||||
});
|
||||
|
||||
//handle import requests
|
||||
app.post('/p/:pad/import', function(req, res, next)
|
||||
{
|
||||
//if abiword is disabled, skip handling this request
|
||||
if(settings.abiword == null)
|
||||
{
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
res.header("Server", serverName);
|
||||
importHandler.doImport(req, res, req.params.pad);
|
||||
});
|
||||
|
||||
//serve index.html under /
|
||||
app.get('/', function(req, res)
|
||||
{
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
"keywords" : ["etherpad", "realtime", "collaborative", "editor"],
|
||||
"author" : "Peter 'Pita' Martischka <petermartischka@googlemail.com>",
|
||||
"contributors": [
|
||||
{ "name": "Hans Pinckaers"}
|
||||
{ "name": "John McLear",
|
||||
"name": "Hans Pinckaers"}
|
||||
],
|
||||
"dependencies" : {
|
||||
"socket.io" : "0.7.7",
|
||||
|
@ -15,7 +16,8 @@
|
|||
"express" : "2.4.2",
|
||||
"clean-css" : "0.2.4",
|
||||
"uglify-js" : "1.0.4",
|
||||
"gzip" : "0.1.0"
|
||||
"gzip" : "0.1.0",
|
||||
"formidable" : "1.0.2"
|
||||
},
|
||||
"version" : "0.0.4"
|
||||
}
|
||||
|
|
|
@ -24,9 +24,9 @@ var padimpexp = (function()
|
|||
|
||||
function addImportFrames()
|
||||
{
|
||||
$("#impexp-import .importframe").remove();
|
||||
$('#impexp-import').append(
|
||||
$('<iframe style="display: none;" name="importiframe" class="importframe"></iframe>'));
|
||||
$("#import .importframe").remove();
|
||||
var iframe = $('<iframe style="display: none;" name="importiframe" class="importframe"></iframe>');
|
||||
$('#import').append(iframe);
|
||||
}
|
||||
|
||||
function fileInputUpdated()
|
||||
|
@ -88,6 +88,11 @@ var padimpexp = (function()
|
|||
}, 0);
|
||||
$('#importarrow').stop(true, true).hide();
|
||||
$('#importstatusball').show();
|
||||
|
||||
$("#import .importframe").load(function()
|
||||
{
|
||||
importDone();
|
||||
});
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -225,6 +230,8 @@ var padimpexp = (function()
|
|||
var self = {
|
||||
init: function()
|
||||
{
|
||||
$("#importform").get(0).setAttribute('action', document.location.href + "/import");
|
||||
|
||||
$("#impexp-close").click(function()
|
||||
{
|
||||
paddocbar.setShownPanel(null);
|
||||
|
@ -249,13 +256,13 @@ var padimpexp = (function()
|
|||
disable: function()
|
||||
{
|
||||
$("#impexp-disabled-clickcatcher").show();
|
||||
$("#impexp-import").css('opacity', 0.5);
|
||||
$("#import").css('opacity', 0.5);
|
||||
$("#impexp-export").css('opacity', 0.5);
|
||||
},
|
||||
enable: function()
|
||||
{
|
||||
$("#impexp-disabled-clickcatcher").hide();
|
||||
$("#impexp-import").css('opacity', 1);
|
||||
$("#import").css('opacity', 1);
|
||||
$("#impexp-export").css('opacity', 1);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -208,7 +208,7 @@ We removed this feature cause its not worth the space it needs in the editbar
|
|||
|
||||
<div id="import">
|
||||
Import from text file, HTML, Word, or RTF:<br/><br/>
|
||||
<form id="importform" method="post" action="import" target="imporiframe" enctype="multipart/form-data">
|
||||
<form id="importform" method="post" action="" target="importiframe" enctype="multipart/form-data">
|
||||
<div class="importformdiv" id="importformfilediv">
|
||||
<input type="file" name="file" size="20" id="importfileinput" />
|
||||
<div class="importmessage" id="importmessagefail"></div>
|
||||
|
|
Loading…
Reference in New Issue