work in progress js_uploader plugin, turn java uploader into plugin - not done yet

This commit is contained in:
Friendika 2011-01-26 00:34:39 -08:00
parent abbd498a8b
commit 2fc89deaea
68 changed files with 6768 additions and 0 deletions

View file

@ -0,0 +1,125 @@
/*
* Copyright 2010 Blue Lotus Software, LLC.
* Copyright 2010 John Yeary <jyeary@bluelotussoftware.com>.
* Copyright 2010 Allan O'Driscoll
*
* Dual Licensed MIT and GPL v.2
*
* The MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*
* The GNU General Public License (GPL) Version 2, June 1991
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; version 2 of the License.
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.bluelotussoftware.apache.commons.fileupload.example;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
/**
* Reads an <code>application/octet-stream</code> and writes it to a file.
* @author John Yeary <jyeary@bluelotussoftware.com>
* @author Allan O'Driscoll
* @version 1.0
*/
public class OctetStreamReader extends HttpServlet {
private static final long serialVersionUID = 6748857432950840322L;
private static final String DESTINATION_DIR_PATH = "files";
private static String realPath;
/**
* {@inheritDoc}
* @param config
* @throws ServletException
*/
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
realPath = getServletContext().getRealPath(DESTINATION_DIR_PATH) + "/";
}
/**
* Handles the HTTP <code>POST</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException {
PrintWriter writer = null;
InputStream is = null;
FileOutputStream fos = null;
try {
writer = response.getWriter();
} catch (IOException ex) {
log(OctetStreamReader.class.getName() + "has thrown an exception: " + ex.getMessage());
}
String filename = request.getHeader("X-File-Name");
try {
is = request.getInputStream();
fos = new FileOutputStream(new File(realPath + filename));
IOUtils.copy(is, fos);
response.setStatus(response.SC_OK);
writer.print("{success: true}");
} catch (FileNotFoundException ex) {
response.setStatus(response.SC_INTERNAL_SERVER_ERROR);
writer.print("{success: false}");
log(OctetStreamReader.class.getName() + "has thrown an exception: " + ex.getMessage());
} catch (IOException ex) {
response.setStatus(response.SC_INTERNAL_SERVER_ERROR);
writer.print("{success: false}");
log(OctetStreamReader.class.getName() + "has thrown an exception: " + ex.getMessage());
} finally {
try {
fos.close();
is.close();
} catch (IOException ignored) {
}
}
writer.flush();
writer.close();
}
}

View file

@ -0,0 +1 @@
<!--- AJAX FileUploader for ColdFusion version: 1.1.1 feedback: sid.maestre@designovermatter.com -----------update history---------------- 1.1.1 on 9/30/2010 by Martin Webb <martin[at]cubicstate.com> - Change function for Upload to returnformat equals JSON - local var scoping. 1.1 on 9/9/2010 by Sid Maestre - Split Upload function to handle fallback uploads for browsers that don't support XHR data transfer ---> <cfcomponent hint="I handle AJAX File Uploads from Valum's AJAX file uploader library"> <cffunction name="Upload" access="remote" output="false" returntype="any" returnformat="JSON"> <cfargument name="qqfile" type="string" required="true"> <cfset var local = structNew()> <cfset local.response = structNew()> <cfset local.requestData = GetHttpRequestData()> <!--- check if XHR data exists ---> <cfif len(local.requestData.content) GT 0> <cfset local.response = UploadFileXhr(arguments.qqfile, local.requestData.content)> <cfelse> <!--- no XHR data process as standard form submission ---> <cffile action="upload" fileField="arguments.qqfile" destination="#ExpandPath('.')#" nameConflict="makeunique"> <cfset local.response['success'] = true> <cfset local.response['type'] = 'form'> </cfif> <cfreturn local.response> </cffunction> <cffunction name="UploadFileXhr" access="private" output="false" returntype="struct"> <cfargument name="qqfile" type="string" required="true"> <cfargument name="content" type="any" required="true"> <cfset var local = structNew()> <cfset local.response = structNew()> <!--- write the contents of the http request to a file. The filename is passed with the qqfile variable ---> <cffile action="write" file="#ExpandPath('.')#/#arguments.qqfile#" output="#arguments.content#"> <!--- if you want to return some JSON you can do it here. I'm just passing a success message ---> <cfset local.response['success'] = true> <cfset local.response['type'] = 'xhr'> <cfreturn local.response> </cffunction> </cfcomponent>

View file

@ -0,0 +1 @@
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <link href="fileuploader.css" rel="stylesheet" type="text/css"> <style> body {font-size:13px; font-family:arial, sans-serif; width:700px; margin:100px auto;} </style> </head> <body > <h1>ColdFusion File Uploader Demo</h1> <p><a href="http://github.com/valums/file-uploader">Back to project page</a></p> <p>To upload a file, click on the button below. Drag-and-drop is supported in FF, Chrome.</p> <p>Progress-bar is supported in FF3.6+, Chrome6+, Safari4+</p> <div id="file-uploader-demo1"> <noscript> <p>Please enable JavaScript to use file uploader.</p> <!-- or put a simple form for upload here --> </noscript> </div> <script src="fileuploader.js" type="text/javascript"></script> <script> function createUploader(){ var uploader = new qq.FileUploader({ element: document.getElementById('file-uploader-demo1'), action: '/valums/server/coldfusion.cfc', params: {method: 'Upload'} }); } // in your app create uploader as soon as the DOM is ready // don't wait for the window to load window.onload = createUploader; </script> </body> </html>

View file

@ -0,0 +1,9 @@
Coldfusion example by Sidney Maestre
http://www.designovermatter.com/post.cfm/ajax-file-uploader-for-coldfusion
1. Unzip Andrew's AJAX Uploader into your web root.
2. Replace the demo.htm with demo.cfm in the "client" folder
3. Place coldfusion.cfc in the "server" folder
4. Browse to the demo.cfm file and try it out. The file should be written to the "server" folder.
Questions? You can contact Sidney Maestreme by mail (sid.maestre(at)designovermatter.com) or Twitter @SidneyAllen

View file

@ -0,0 +1,62 @@
#!/usr/bin/perl
use strict;
use CGI::Carp qw(fatalsToBrowser);
use Digest::MD5;
my $uploaddir = '/folder/to/save/in/ajax_upload/tmp_uploads';
my $maxFileSize = 0.5 * 1024 * 1024; # 1/2mb max file size...
use CGI;
my $IN = new CGI;
my $file = $IN->param('POSTDATA');
my $temp_id = $IN->param('temp_id');
# make a random filename, and we guess the file type later on...
my $name = Digest::MD5::md5_base64( rand );
$name =~ s/\+/_/g;
$name =~ s/\//_/g;
my $type;
if ($file =~ /^GIF/) {
$type = "gif";
} elsif ($file =~ /PNG/) {
$type = "png";
} elsif ($file =~ /JFIF/) {
$type = "jpg";
}
if (!$type) {
print qq|{ "success": false, "error": "Invalid file type..." }|;
print STDERR "file has been NOT been uploaded... \n";
}
print STDERR "Making dir: $uploaddir/$temp_id \n";
mkdir("$uploaddir/$temp_id");
open(WRITEIT, ">$uploaddir/$name.$type") or die "Cant write to $uploaddir/$name.$type. Reason: $!";
print WRITEIT $file;
close(WRITEIT);
my $check_size = -s "$uploaddir/$name.$type";
print STDERR qq|Main filesize: $check_size Max Filesize: $maxFileSize \n\n|;
print $IN->header();
if ($check_size < 1) {
print STDERR "ooops, its empty - gonna get rid of it!\n";
print qq|{ "success": false, "error": "File is empty..." }|;
print STDERR "file has been NOT been uploaded... \n";
} elsif ($check_size > $maxFileSize) {
print STDERR "ooops, its too large - gonna get rid of it!\n";
print qq|{ "success": false, "error": "File is too large..." }|;
print STDERR "file has been NOT been uploaded... \n";
} else {
print qq|{ "success": true }|;
print STDERR "file has been successfully uploaded... thank you.\n";
}

View file

@ -0,0 +1,162 @@
<?php
/**
* Handle file uploads via XMLHttpRequest
*/
class qqUploadedFileXhr {
/**
* Save the file to the specified path
* @return boolean TRUE on success
*/
function save($path) {
$input = fopen("php://input", "r");
$temp = tmpfile();
$realSize = stream_copy_to_stream($input, $temp);
fclose($input);
if ($realSize != $this->getSize()){
return false;
}
$target = fopen($path, "w");
fseek($temp, 0, SEEK_SET);
stream_copy_to_stream($temp, $target);
fclose($target);
return true;
}
function getName() {
return $_GET['qqfile'];
}
function getSize() {
if (isset($_SERVER["CONTENT_LENGTH"])){
return (int)$_SERVER["CONTENT_LENGTH"];
} else {
throw new Exception('Getting content length is not supported.');
}
}
}
/**
* Handle file uploads via regular form post (uses the $_FILES array)
*/
class qqUploadedFileForm {
/**
* Save the file to the specified path
* @return boolean TRUE on success
*/
function save($path) {
if(!move_uploaded_file($_FILES['qqfile']['tmp_name'], $path)){
return false;
}
return true;
}
function getName() {
return $_FILES['qqfile']['name'];
}
function getSize() {
return $_FILES['qqfile']['size'];
}
}
class qqFileUploader {
private $allowedExtensions = array();
private $sizeLimit = 10485760;
private $file;
function __construct(array $allowedExtensions = array(), $sizeLimit = 10485760){
$allowedExtensions = array_map("strtolower", $allowedExtensions);
$this->allowedExtensions = $allowedExtensions;
$this->sizeLimit = $sizeLimit;
$this->checkServerSettings();
if (isset($_GET['qqfile'])) {
$this->file = new qqUploadedFileXhr();
} elseif (isset($_FILES['qqfile'])) {
$this->file = new qqUploadedFileForm();
} else {
$this->file = false;
}
}
private function checkServerSettings(){
$postSize = $this->toBytes(ini_get('post_max_size'));
$uploadSize = $this->toBytes(ini_get('upload_max_filesize'));
if ($postSize < $this->sizeLimit || $uploadSize < $this->sizeLimit){
$size = max(1, $this->sizeLimit / 1024 / 1024) . 'M';
die("{'error':'increase post_max_size and upload_max_filesize to $size'}");
}
}
private function toBytes($str){
$val = trim($str);
$last = strtolower($str[strlen($str)-1]);
switch($last) {
case 'g': $val *= 1024;
case 'm': $val *= 1024;
case 'k': $val *= 1024;
}
return $val;
}
/**
* Returns array('success'=>true) or array('error'=>'error message')
*/
function handleUpload($uploadDirectory, $replaceOldFile = FALSE){
if (!is_writable($uploadDirectory)){
return array('error' => "Server error. Upload directory isn't writable.");
}
if (!$this->file){
return array('error' => 'No files were uploaded.');
}
$size = $this->file->getSize();
if ($size == 0) {
return array('error' => 'File is empty');
}
if ($size > $this->sizeLimit) {
return array('error' => 'File is too large');
}
$pathinfo = pathinfo($this->file->getName());
$filename = $pathinfo['filename'];
//$filename = md5(uniqid());
$ext = $pathinfo['extension'];
if($this->allowedExtensions && !in_array(strtolower($ext), $this->allowedExtensions)){
$these = implode(', ', $this->allowedExtensions);
return array('error' => 'File has an invalid extension, it should be one of '. $these . '.');
}
if(!$replaceOldFile){
/// don't overwrite previous files that were uploaded
while (file_exists($uploadDirectory . $filename . '.' . $ext)) {
$filename .= rand(10, 99);
}
}
if ($this->file->save($uploadDirectory . $filename . '.' . $ext)){
return array('success'=>true);
} else {
return array('error'=> 'Could not save uploaded file.' .
'The upload was cancelled, or server error encountered');
}
}
}
// list of valid extensions, ex. array("jpeg", "xml", "bmp")
$allowedExtensions = array();
// max file size in bytes
$sizeLimit = 10 * 1024 * 1024;
$uploader = new qqFileUploader($allowedExtensions, $sizeLimit);
$result = $uploader->handleUpload('uploads/');
// to pass data through iframe you will need to encode all html tags
echo htmlspecialchars(json_encode($result), ENT_NOQUOTES);

View file

@ -0,0 +1,18 @@
The server-side code should consist of two parts.
1. For IE6-8, Opera, older versions of other browsers you get the file as
you normally do with regular form-base uploads.
2. For browsers which upload file with progress bar, you will need to get the raw
post data and write it to the file.
## Return values ##
You should return json as a text/html, and escape all
'<' as '&lt;', '>' as '&gt;', and '&' as '&amp;'.
Return
{"success":true} when upload was successful
{"error":"error message to display"} in case of error
Send me a mail to andrew (at) valums.com, if you will have any questions.

View file

@ -0,0 +1,2 @@
*
!.gitignore