From 8e96bab92281d5f8dc166d8d9eb5f8c8f5f37879 Mon Sep 17 00:00:00 2001 From: Egil Moeller Date: Sun, 4 Apr 2010 02:37:29 +0200 Subject: Added a fileUpload plugin --- .../plugins/fileUpload/controllers/fileUpload.js | 87 ++++++++++++++++++++ etherpad/src/plugins/fileUpload/hooks.js | 11 +++ etherpad/src/plugins/fileUpload/main.js | 19 +++++ etherpad/src/plugins/fileUpload/models.js | 95 ++++++++++++++++++++++ .../plugins/fileUpload/templates/fileUpload.ejs | 32 ++++++++ .../plugins/fileUpload/templates/fileUploaded.ejs | 5 ++ 6 files changed, 249 insertions(+) create mode 100644 etherpad/src/plugins/fileUpload/controllers/fileUpload.js create mode 100644 etherpad/src/plugins/fileUpload/hooks.js create mode 100644 etherpad/src/plugins/fileUpload/main.js create mode 100644 etherpad/src/plugins/fileUpload/models.js create mode 100644 etherpad/src/plugins/fileUpload/templates/fileUpload.ejs create mode 100644 etherpad/src/plugins/fileUpload/templates/fileUploaded.ejs diff --git a/etherpad/src/plugins/fileUpload/controllers/fileUpload.js b/etherpad/src/plugins/fileUpload/controllers/fileUpload.js new file mode 100644 index 0000000..d6585f1 --- /dev/null +++ b/etherpad/src/plugins/fileUpload/controllers/fileUpload.js @@ -0,0 +1,87 @@ +/** + * Copyright 2009 RedHog, Egil Möller + * + * 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. + */ + +import("faststatic"); +import("dispatch.{Dispatcher,PrefixMatcher,forward}"); + +import("etherpad.utils.*"); +import("etherpad.collab.server_utils"); +import("etherpad.globals.*"); +import("etherpad.log"); +import("etherpad.pad.padusers"); +import("etherpad.pro.pro_utils"); +import("etherpad.helpers"); +import("etherpad.pro.pro_accounts.getSessionProAccount"); +import("sqlbase.sqlbase"); +import("sqlbase.sqlcommon"); +import("sqlbase.sqlobj"); +import("plugins.fileUpload.models"); +jimport("org.apache.commons.fileupload"); + +function onRequest() { + var isPro = pro_utils.isProDomainRequest(); + var userId = padusers.getUserId(); + + + helpers.addClientVars({ + userAgent: request.headers["User-Agent"], + debugEnabled: request.params.djs, + clientIp: request.clientAddr, + colorPalette: COLOR_PALETTE, + serverTimestamp: +(new Date), + isProPad: isPro, + userIsGuest: padusers.isGuest(userId), + userId: userId, + }); + + var isProUser = (isPro && ! padusers.isGuest(userId)); + + if (request.isPost) { + var uploads = []; + var itemFactory = new fileupload.disk.DiskFileItemFactory(); + var handler = new fileupload.servlet.ServletFileUpload(itemFactory); + var items = handler.parseRequest(request.underlying).toArray(); + for (var i = 0; i < items.length; i++){ + if (!items[i].isFormField()) + uploads.push('/up/' + models.storeFile(items[i])); + } + + response.setContentType("text/json; charset=utf-8"); + response.write( + renderTemplateAsString( + "fileUploaded.ejs", + { + uploads: uploads, + isPro: isPro, + isProAccountHolder: isProUser, + account: getSessionProAccount(), // may be falsy + }, + 'fileUpload')); + if (request.acceptsGzip) { + response.setGzip(true); + } + } else { + renderHtml( + "fileUpload.ejs", + { + isPro: isPro, + isProAccountHolder: isProUser, + account: getSessionProAccount(), // may be falsy + }, + 'fileUpload'); + } + return true; +} diff --git a/etherpad/src/plugins/fileUpload/hooks.js b/etherpad/src/plugins/fileUpload/hooks.js new file mode 100644 index 0000000..0948c17 --- /dev/null +++ b/etherpad/src/plugins/fileUpload/hooks.js @@ -0,0 +1,11 @@ +import("etherpad.log"); +import("faststatic"); +import("etherpad.utils.*"); +import("etherpad.globals.*"); +import("dispatch.{Dispatcher,PrefixMatcher,forward}"); +import("plugins.fileUpload.controllers.fileUpload"); + +function handlePath() { + return [[PrefixMatcher('/ep/fileUpload/'), forward(fileUpload)], + [PrefixMatcher('/up/'), faststatic.directoryServer('/plugins/fileUpload/upload/', {cache: isProduction()})]]; +} diff --git a/etherpad/src/plugins/fileUpload/main.js b/etherpad/src/plugins/fileUpload/main.js new file mode 100644 index 0000000..5ff105f --- /dev/null +++ b/etherpad/src/plugins/fileUpload/main.js @@ -0,0 +1,19 @@ +import("etherpad.log"); +import("plugins.fileUpload.hooks"); + +function init() { + this.hooks = ['handlePath']; + this.description = 'File upload manager'; + this.handlePath = hooks.handlePath; + this.install = install; + this.uninstall = uninstall; +} + +function install() { + log.info("Installing fileUpload"); +} + +function uninstall() { + log.info("Uninstalling fileUpload"); +} + diff --git a/etherpad/src/plugins/fileUpload/models.js b/etherpad/src/plugins/fileUpload/models.js new file mode 100644 index 0000000..f8fb563 --- /dev/null +++ b/etherpad/src/plugins/fileUpload/models.js @@ -0,0 +1,95 @@ +/** + * Copyright 2009 RedHog, Egil Möller + * + * 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. + */ + +import("etherpad.utils.*"); +import("etherpad.globals.*"); +import("etherpad.log"); +import("sqlbase.sqlbase"); +import("sqlbase.sqlcommon"); +import("sqlbase.sqlobj"); + +jimport("java.io.File", + "java.io.DataInputStream", + "java.io.FileInputStream", + "java.lang.Byte", + "java.io.FileReader", + "java.io.BufferedReader", + "java.security.MessageDigest", + "java.lang.Runtime"); + + +/* Normal base64 encoding, except we don't care about adding newlines */ +function base64Encode(stringArray) { + base64code = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789" + "+/"; + + /* Pad array to nearest three byte multiple */ + var padding = (3 - (stringArray.length % 3)) % 3; + var padded = java.lang.reflect.Array.newInstance(Byte.TYPE, stringArray.length + padding); + java.lang.System.arraycopy(stringArray, 0, padded, 0, stringArray.length); + stringArray = padded; + + var encoded = ""; + for (var i = 0; i < stringArray.length; i += 3) { + var j = (((stringArray[i] & 0xff) << 16) + + ((stringArray[i + 1] & 0xff) << 8) + + (stringArray[i + 2] & 0xff)); + encoded = (encoded + + base64code.charAt((j >> 18) & 0x3f) + + base64code.charAt((j >> 12) & 0x3f) + + base64code.charAt((j >> 6) & 0x3f) + + base64code.charAt(j & 0x3f)); + } + /* replace padding with "=" */ + return encoded.substring(0, encoded.length - padding) + "==".substring(0, padding); +} + + +function makeSymlink(destination, source) { + return Runtime.getRuntime().exec(['ln', '-s', source.getPath(), destination.getPath()]).waitFor(); +} + + +/* Reads a File and updates a digest with its content */ +function updateDigestFromFile(digest, file) { + var handle = new java.io.FileInputStream(file); + + var bytes = java.lang.reflect.Array.newInstance(Byte.TYPE, 512); + var nbytes = 0; + + while ((nbytes = handle.read(bytes, 0, 512)) != -1) + digest.update(bytes, 0, nbytes); + + handle.close(); +} + + +/* Stores a org.apache.commons.fileupload.disk.DiskFileItem permanently and returns a filename. */ +function storeFile(fileItem) { + var nameParts = fileItem.name.split('.'); + var extension = nameParts[nameParts.length-1]; + + var digest = MessageDigest.getInstance("SHA1"); + updateDigestFromFile(digest, fileItem.getStoreLocation()); + var checksum = base64Encode(digest.digest()); + + fileItem.write(File("src/plugins/fileUpload/upload/" + checksum)); + + makeSymlink( + File("src/plugins/fileUpload/upload/" + checksum + '.' + extension), + File(checksum)); + + return checksum + '.' + extension; +} diff --git a/etherpad/src/plugins/fileUpload/templates/fileUpload.ejs b/etherpad/src/plugins/fileUpload/templates/fileUpload.ejs new file mode 100644 index 0000000..57f33e6 --- /dev/null +++ b/etherpad/src/plugins/fileUpload/templates/fileUpload.ejs @@ -0,0 +1,32 @@ +<% /* Copyright 2009 Google Inc. + +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. */ %> +<% + helpers.setHtmlTitle("Test plugin"); + helpers.setBodyId("padbody"); + helpers.addBodyClass("limwidth nonpropad nonprouser"); + helpers.includeCss("pad2_ejs.css"); + helpers.setRobotsPolicy({index: false, follow: false}) + helpers.includeJQuery(); + helpers.includeCometJs(); + helpers.includeJs("json2.js"); + helpers.addToHead('\n\n'); +%> + +
+
+ + +
+ +
diff --git a/etherpad/src/plugins/fileUpload/templates/fileUploaded.ejs b/etherpad/src/plugins/fileUpload/templates/fileUploaded.ejs new file mode 100644 index 0000000..5a62f7e --- /dev/null +++ b/etherpad/src/plugins/fileUpload/templates/fileUploaded.ejs @@ -0,0 +1,5 @@ +[ +<% for (var i = 0; i < uploads.length; i++) { %> + '<%= uploads[i] %>', +<% } %> +] -- cgit v1.2.3-1-g7c22 From 055d46499218be2902c713fb37ae3a1394484761 Mon Sep 17 00:00:00 2001 From: Egil Moeller Date: Sun, 4 Apr 2010 02:42:25 +0200 Subject: Oups, forgot some new dependencies for handling mime/multipart --- .../lib/commons-fileupload-1.2.1-javadoc.jar | Bin 0 -> 275779 bytes .../lib/commons-fileupload-1.2.1-sources.jar | Bin 0 -> 73721 bytes infrastructure/lib/commons-fileupload-1.2.1.jar | Bin 0 -> 57779 bytes infrastructure/lib/commons-io-1.4-javadoc.jar | Bin 0 -> 499643 bytes infrastructure/lib/commons-io-1.4-sources.jar | Bin 0 -> 163177 bytes infrastructure/lib/commons-io-1.4.jar | Bin 0 -> 109043 bytes 6 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 infrastructure/lib/commons-fileupload-1.2.1-javadoc.jar create mode 100644 infrastructure/lib/commons-fileupload-1.2.1-sources.jar create mode 100644 infrastructure/lib/commons-fileupload-1.2.1.jar create mode 100644 infrastructure/lib/commons-io-1.4-javadoc.jar create mode 100644 infrastructure/lib/commons-io-1.4-sources.jar create mode 100644 infrastructure/lib/commons-io-1.4.jar diff --git a/infrastructure/lib/commons-fileupload-1.2.1-javadoc.jar b/infrastructure/lib/commons-fileupload-1.2.1-javadoc.jar new file mode 100644 index 0000000..86a56ac Binary files /dev/null and b/infrastructure/lib/commons-fileupload-1.2.1-javadoc.jar differ diff --git a/infrastructure/lib/commons-fileupload-1.2.1-sources.jar b/infrastructure/lib/commons-fileupload-1.2.1-sources.jar new file mode 100644 index 0000000..8141625 Binary files /dev/null and b/infrastructure/lib/commons-fileupload-1.2.1-sources.jar differ diff --git a/infrastructure/lib/commons-fileupload-1.2.1.jar b/infrastructure/lib/commons-fileupload-1.2.1.jar new file mode 100644 index 0000000..aa209b3 Binary files /dev/null and b/infrastructure/lib/commons-fileupload-1.2.1.jar differ diff --git a/infrastructure/lib/commons-io-1.4-javadoc.jar b/infrastructure/lib/commons-io-1.4-javadoc.jar new file mode 100644 index 0000000..95731a7 Binary files /dev/null and b/infrastructure/lib/commons-io-1.4-javadoc.jar differ diff --git a/infrastructure/lib/commons-io-1.4-sources.jar b/infrastructure/lib/commons-io-1.4-sources.jar new file mode 100644 index 0000000..299708f Binary files /dev/null and b/infrastructure/lib/commons-io-1.4-sources.jar differ diff --git a/infrastructure/lib/commons-io-1.4.jar b/infrastructure/lib/commons-io-1.4.jar new file mode 100644 index 0000000..133dc6c Binary files /dev/null and b/infrastructure/lib/commons-io-1.4.jar differ -- cgit v1.2.3-1-g7c22