Commit 62e4b2a5 authored by Trino Parra's avatar Trino Parra

www

parent e313b779
/**
* @fileoverview Magic dependency loading. Taken from script.aculo.us
* and modified to break it.
* @author Stefan Strigler steve@zeank.in-berlin.de
*/
/*exported JSJaC */
var JSJaC = {
Version: '1.4',
require: function(libraryName) {
/*jshint evil: true */
// inserting via DOM fails in Safari 2.0, so brute force approach
document.write('<script type="text/javascript" src="'+libraryName+'"></script>');
},
load: function() {
var includes =
['xmlextras',
'jsextras',
'crypt',
'JSJaCConfig',
'JSJaCConstants',
'JSJaCCookie',
'JSJaCJSON',
'JSJaCJID',
'JSJaCUtils',
'JSJaCBuilder',
'JSJaCPacket',
'JSJaCError',
'JSJaCKeys',
'JSJaCConnection',
'JSJaCHttpPollingConnection',
'JSJaCHttpBindingConnection',
'JSJaCConsoleLogger',
'JSJaCWebSocketConnection'
];
var scripts = document.getElementsByTagName("script");
var path = './', i;
for (i=0; i<scripts.length; i++) {
if (scripts.item(i).src && scripts.item(i).src.match(/JSJaC\.js$/)) {
path = scripts.item(i).src.replace(/JSJaC.js$/,'');
break;
}
}
for (i=0; i<includes.length; i++)
this.require(path+includes[i]+'.js');
},
bind: function(fn, obj, optArg) {
return function(arg) {
return fn.apply(obj, [arg, optArg]);
};
}
};
if (typeof JSJaCConnection == 'undefined')
JSJaC.load();
Please follow these pull request guidelines:
1. Update your fork to the latest upstream version.
2. Follow the coding conventions of the original source files (indentation, spaces, brackets layout).
3. Code changes must pass JSHint validation with the `.jshintrc` settings of this project.
4. Code changes must pass the QUnit tests defined in the `test` folder.
5. New features should be covered by accompanying QUnit tests.
6. Keep your commits as atomic as possible, i.e. create a new commit for every single bug fix or feature added.
7. Always add meaningful commit messages.
MIT License
Copyright © 2010 Sebastian Tschan, https://blueimp.net
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.
# jQuery File Upload Plugin
## Demo
[Demo File Upload](https://blueimp.github.io/jQuery-File-Upload/)
## Description
File Upload widget with multiple file selection, drag&amp;drop support, progress bars, validation and preview images, audio and video for jQuery.
Supports cross-domain, chunked and resumable file uploads and client-side image resizing. Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.
## Setup
* [How to setup the plugin on your website](https://github.com/blueimp/jQuery-File-Upload/wiki/Setup)
* [How to use only the basic plugin (minimal setup guide).](https://github.com/blueimp/jQuery-File-Upload/wiki/Basic-plugin)
## Features
* **Multiple file upload:**
Allows to select multiple files at once and upload them simultaneously.
* **Drag & Drop support:**
Allows to upload files by dragging them from your desktop or filemanager and dropping them on your browser window.
* **Upload progress bar:**
Shows a progress bar indicating the upload progress for individual files and for all uploads combined.
* **Cancelable uploads:**
Individual file uploads can be canceled to stop the upload progress.
* **Resumable uploads:**
Aborted uploads can be resumed with browsers supporting the Blob API.
* **Chunked uploads:**
Large files can be uploaded in smaller chunks with browsers supporting the Blob API.
* **Client-side image resizing:**
Images can be automatically resized on client-side with browsers supporting the required JS APIs.
* **Preview images, audio and video:**
A preview of image, audio and video files can be displayed before uploading with browsers supporting the required APIs.
* **No browser plugins (e.g. Adobe Flash) required:**
The implementation is based on open standards like HTML5 and JavaScript and requires no additional browser plugins.
* **Graceful fallback for legacy browsers:**
Uploads files via XMLHttpRequests if supported and uses iframes as fallback for legacy browsers.
* **HTML file upload form fallback:**
Allows progressive enhancement by using a standard HTML file upload form as widget element.
* **Cross-site file uploads:**
Supports uploading files to a different domain with cross-site XMLHttpRequests or iframe redirects.
* **Multiple plugin instances:**
Allows to use multiple plugin instances on the same webpage.
* **Customizable and extensible:**
Provides an API to set individual options and define callback methods for various upload events.
* **Multipart and file contents stream uploads:**
Files can be uploaded as standard "multipart/form-data" or file contents stream (HTTP PUT file upload).
* **Compatible with any server-side application platform:**
Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.
## Requirements
### Mandatory requirements
* [jQuery](https://jquery.com/) v. 1.6+
* [jQuery UI widget factory](https://api.jqueryui.com/jQuery.widget/) v. 1.9+ (included): Required for the basic File Upload plugin, but very lightweight without any other dependencies from the jQuery UI suite.
* [jQuery Iframe Transport plugin](https://github.com/blueimp/jQuery-File-Upload/blob/master/js/jquery.iframe-transport.js) (included): Required for [browsers without XHR file upload support](https://github.com/blueimp/jQuery-File-Upload/wiki/Browser-support).
### Optional requirements
* [JavaScript Templates engine](https://github.com/blueimp/JavaScript-Templates) v. 2.5.4+: Used to render the selected and uploaded files for the Basic Plus UI and jQuery UI versions.
* [JavaScript Load Image library](https://github.com/blueimp/JavaScript-Load-Image) v. 1.13.0+: Required for the image previews and resizing functionality.
* [JavaScript Canvas to Blob polyfill](https://github.com/blueimp/JavaScript-Canvas-to-Blob) v. 2.1.1+:Required for the image previews and resizing functionality.
* [blueimp Gallery](https://github.com/blueimp/Gallery) v. 2.15.1+: Used to display the uploaded images in a lightbox.
* [Bootstrap](http://getbootstrap.com/) v. 3.2.0+
* [Glyphicons](http://glyphicons.com/)
The user interface of all versions, except the jQuery UI version, is built with [Bootstrap](http://getbootstrap.com/) and icons from [Glyphicons](http://glyphicons.com/).
### Cross-domain requirements
[Cross-domain File Uploads](https://github.com/blueimp/jQuery-File-Upload/wiki/Cross-domain-uploads) using the [Iframe Transport plugin](https://github.com/blueimp/jQuery-File-Upload/blob/master/js/jquery.iframe-transport.js) require a redirect back to the origin server to retrieve the upload results. The [example implementation](https://github.com/blueimp/jQuery-File-Upload/blob/master/js/main.js) makes use of [result.html](https://github.com/blueimp/jQuery-File-Upload/blob/master/cors/result.html) as a static redirect page for the origin server.
The repository also includes the [jQuery XDomainRequest Transport plugin](https://github.com/blueimp/jQuery-File-Upload/blob/master/js/cors/jquery.xdr-transport.js), which enables limited cross-domain AJAX requests in Microsoft Internet Explorer 8 and 9 (IE 10 supports cross-domain XHR requests).
The XDomainRequest object allows GET and POST requests only and doesn't support file uploads. It is used on the [Demo](https://blueimp.github.io/jQuery-File-Upload/) to delete uploaded files from the cross-domain demo file upload service.
### Custom Backends
You can add support for various backends by adhering to the specification [outlined here](https://github.com/blueimp/jQuery-File-Upload/wiki/JSON-Response).
## Browsers
### Desktop browsers
The File Upload plugin is regularly tested with the latest browser versions and supports the following minimal versions:
* Google Chrome
* Apple Safari 4.0+
* Mozilla Firefox 3.0+
* Opera 11.0+
* Microsoft Internet Explorer 6.0+
### Mobile browsers
The File Upload plugin has been tested with and supports the following mobile browsers:
* Apple Safari on iOS 6.0+
* Google Chrome on iOS 6.0+
* Google Chrome on Android 4.0+
* Default Browser on Android 2.3+
* Opera Mobile 12.0+
### Supported features
For a detailed overview of the features supported by each browser version, please have a look at the [Extended browser support information](https://github.com/blueimp/jQuery-File-Upload/wiki/Browser-support).
## Contributing
**Bug fixes** and **new features** can be proposed using [pull requests](https://github.com/blueimp/jQuery-File-Upload/pulls).
Please read the [contribution guidelines](https://github.com/blueimp/jQuery-File-Upload/blob/master/CONTRIBUTING.md) before submitting a pull request.
## Support
This project is actively maintained, but there is no official support channel.
If you have a question that another developer might help you with, please post to [Stack Overflow](http://stackoverflow.com/questions/tagged/blueimp+jquery+file-upload) and tag your question with `blueimp jquery file upload`.
## License
Released under the [MIT license](https://opensource.org/licenses/MIT).
#!/usr/bin/env node
'use strict';
var path = require('path');
var packageJSON = require(path.join(__dirname, 'package.json'));
var bowerFile = path.join(__dirname, 'bower.json');
var bowerJSON = require('bower-json').parse(
require(bowerFile),
{normalize: true}
);
bowerJSON.version = packageJSON.version;
require('fs').writeFileSync(
bowerFile,
JSON.stringify(bowerJSON, null, 2) + '\n'
);
{
"name": "blueimp-file-upload",
"version": "9.21.0",
"title": "jQuery File Upload",
"description": "File Upload widget with multiple file selection, drag&amp;drop support, progress bar, validation and preview images.",
"keywords": [
"jquery",
"file",
"upload",
"widget",
"multiple",
"selection",
"drag",
"drop",
"progress",
"preview",
"cross-domain",
"cross-site",
"chunk",
"resume",
"gae",
"go",
"python",
"php",
"bootstrap"
],
"homepage": "https://github.com/blueimp/jQuery-File-Upload",
"author": {
"name": "Sebastian Tschan",
"url": "https://blueimp.net"
},
"maintainers": [
{
"name": "Sebastian Tschan",
"url": "https://blueimp.net"
}
],
"repository": {
"type": "git",
"url": "git://github.com/blueimp/jQuery-File-Upload.git"
},
"bugs": "https://github.com/blueimp/jQuery-File-Upload/issues",
"license": "MIT",
"dependencies": {
"jquery": ">=1.6",
"blueimp-tmpl": ">=2.5.4",
"blueimp-load-image": ">=1.13.0",
"blueimp-canvas-to-blob": ">=2.1.1"
},
"main": [
"js/jquery.fileupload.js"
],
"ignore": [
"/*.*",
"/cors",
"css/jquery-ui-demo-ie8.css",
"css/jquery-ui-demo.css",
"css/style.css",
"js/app.js",
"js/main.js",
"server",
"test"
]
}
<!DOCTYPE HTML>
<!--
/*
* jQuery File Upload Plugin postMessage API
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2011, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
-->
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery File Upload Plugin postMessage API</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<script>
/*jslint unparam: true, regexp: true */
/*global $, Blob, FormData, location */
'use strict';
var origin = /^http:\/\/example.org/,
target = new RegExp('^(http(s)?:)?\\/\\/' + location.host + '\\/');
$(window).on('message', function (e) {
e = e.originalEvent;
var s = e.data,
xhr = $.ajaxSettings.xhr(),
f;
if (!origin.test(e.origin)) {
throw new Error('Origin "' + e.origin + '" does not match ' + origin);
}
if (!target.test(e.data.url)) {
throw new Error('Target "' + e.data.url + '" does not match ' + target);
}
$(xhr.upload).on('progress', function (ev) {
ev = ev.originalEvent;
e.source.postMessage({
id: s.id,
type: ev.type,
timeStamp: ev.timeStamp,
lengthComputable: ev.lengthComputable,
loaded: ev.loaded,
total: ev.total
}, e.origin);
});
s.xhr = function () {
return xhr;
};
if (!(s.data instanceof Blob)) {
f = new FormData();
$.each(s.data, function (i, v) {
f.append(v.name, v.value);
});
s.data = f;
}
$.ajax(s).always(function (result, statusText, jqXHR) {
if (!jqXHR.done) {
jqXHR = result;
result = null;
}
e.source.postMessage({
id: s.id,
status: jqXHR.status,
statusText: statusText,
result: result,
headers: jqXHR.getAllResponseHeaders()
}, e.origin);
});
});
</script>
</body>
</html>
<!DOCTYPE HTML>
<!--
/*
* jQuery Iframe Transport Plugin Redirect Page
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2010, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
-->
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery Iframe Transport Plugin Redirect Page</title>
</head>
<body>
<script>
document.body.innerText=document.body.textContent=decodeURIComponent(window.location.search.slice(1));
</script>
</body>
</html>
@charset "UTF-8";
/*
* jQuery File Upload Demo CSS Fixes for IE<9
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
.navigation {
list-style: none;
padding: 0;
margin: 1em 0;
}
.navigation li {
display: inline;
margin-right: 10px;
}
@charset "UTF-8";
/*
* jQuery File Upload Demo CSS
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
body {
max-width: 750px;
margin: 0 auto;
padding: 1em;
font-family: "Lucida Grande", "Lucida Sans Unicode", Arial, sans-serif;
font-size: 1em;
line-height: 1.4em;
background: #222;
color: #fff;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
a {
color: orange;
text-decoration: none;
}
img {
border: 0;
vertical-align: middle;
}
h1 {
line-height: 1em;
}
blockquote {
padding: 0 0 0 15px;
margin: 0 0 20px;
border-left: 5px solid #eee;
}
table {
width: 100%;
margin: 10px 0;
}
.fileupload-progress {
margin: 10px 0;
}
.fileupload-progress .progress-extended {
margin-top: 5px;
}
.error {
color: red;
}
@media (min-width: 481px) {
.navigation {
list-style: none;
padding: 0;
}
.navigation li {
display: inline-block;
}
.navigation li:not(:first-child):before {
content: "| ";
}
}
@charset "UTF-8";
/*
* jQuery File Upload Plugin NoScript CSS
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
.fileinput-button input {
position: static;
opacity: 1;
filter: none;
font-size: inherit !important;
direction: inherit;
}
.fileinput-button span {
display: none;
}
@charset "UTF-8";
/*
* jQuery File Upload UI Plugin NoScript CSS
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2012, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
.fileinput-button i,
.fileupload-buttonbar .delete,
.fileupload-buttonbar .toggle {
display: none;
}
@charset "UTF-8";
/*
* jQuery File Upload UI Plugin CSS
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2010, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
.fileupload-buttonbar .btn,
.fileupload-buttonbar .toggle {
margin-bottom: 5px;
}
.progress-animated .progress-bar,
.progress-animated .bar {
background: url("../img/progressbar.gif") !important;
filter: none;
}
.fileupload-process {
float: right;
display: none;
}
.fileupload-processing .fileupload-process,
.files .processing .preview {
display: block;
width: 32px;
height: 32px;
background: url("../img/loading.gif") center no-repeat;
background-size: contain;
}
.files audio,
.files video {
max-width: 300px;
}
@media (max-width: 767px) {
.fileupload-buttonbar .toggle,
.files .toggle,
.files .btn span {
display: none;
}
.files .name {
width: 80px;
word-wrap: break-word;
}
.files audio,
.files video {
max-width: 80px;
}
.files img,
.files canvas {
max-width: 100%;
}
}
@charset "UTF-8";
/*
* jQuery File Upload Plugin CSS
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
.fileinput-button {
position: relative;
overflow: hidden;
display: inline-block;
}
.fileinput-button input {
position: absolute;
top: 0;
right: 0;
margin: 0;
opacity: 0;
-ms-filter: 'alpha(opacity=0)';
font-size: 200px !important;
direction: ltr;
cursor: pointer;
}
/* Fixes for IE < 8 */
@media screen\9 {
.fileinput-button input {
filter: alpha(opacity=0);
font-size: 100%;
height: 100%;
}
}
@charset "UTF-8";
/*
* jQuery File Upload Plugin CSS Example
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
body {
padding-top: 60px;
}
This diff is collapsed.
This diff is collapsed.
/*
* jQuery File Upload Plugin Angular JS Example
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
/* jshint nomen:false */
/* global window, angular */
;(function () {
'use strict';
var isOnGitHub = window.location.hostname === 'blueimp.github.io',
url = isOnGitHub ? '//jquery-file-upload.appspot.com/' : 'server/php/';
angular.module('demo', [
'blueimp.fileupload'
])
.config([
'$httpProvider', 'fileUploadProvider',
function ($httpProvider, fileUploadProvider) {
delete $httpProvider.defaults.headers.common['X-Requested-With'];
fileUploadProvider.defaults.redirect = window.location.href.replace(
/\/[^\/]*$/,
'/cors/result.html?%s'
);
if (isOnGitHub) {
// Demo settings:
angular.extend(fileUploadProvider.defaults, {
// Enable image resizing, except for Android and Opera,
// which actually support image resizing, but fail to
// send Blob objects via XHR requests:
disableImageResize: /Android(?!.*Chrome)|Opera/
.test(window.navigator.userAgent),
maxFileSize: 999000,
acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i
});
}
}
])
.controller('DemoFileUploadController', [
'$scope', '$http', '$filter', '$window',
function ($scope, $http) {
$scope.options = {
url: url
};
if (!isOnGitHub) {
$scope.loadingFiles = true;
$http.get(url)
.then(
function (response) {
$scope.loadingFiles = false;
$scope.queue = response.data.files || [];
},
function () {
$scope.loadingFiles = false;
}
);
}
}
])
.controller('FileDestroyController', [
'$scope', '$http',
function ($scope, $http) {
var file = $scope.file,
state;
if (file.url) {
file.$state = function () {
return state;
};
file.$destroy = function () {
state = 'pending';
return $http({
url: file.deleteUrl,
method: file.deleteType
}).then(
function () {
state = 'resolved';
$scope.clear(file);
},
function () {
state = 'rejected';
}
);
};
} else if (!file.$cancel && !file._index) {
file.$cancel = function () {
$scope.clear(file);
};
}
}
]);
}());
/*
* jQuery postMessage Transport Plugin
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2011, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
/* global define, require, window, document */
;(function (factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node/CommonJS:
factory(require('jquery'));
} else {
// Browser globals:
factory(window.jQuery);
}
}(function ($) {
'use strict';
var counter = 0,
names = [
'accepts',
'cache',
'contents',
'contentType',
'crossDomain',
'data',
'dataType',
'headers',
'ifModified',
'mimeType',
'password',
'processData',
'timeout',
'traditional',
'type',
'url',
'username'
],
convert = function (p) {
return p;
};
$.ajaxSetup({
converters: {
'postmessage text': convert,
'postmessage json': convert,
'postmessage html': convert
}
});
$.ajaxTransport('postmessage', function (options) {
if (options.postMessage && window.postMessage) {
var iframe,
loc = $('<a>').prop('href', options.postMessage)[0],
target = loc.protocol + '//' + loc.host,
xhrUpload = options.xhr().upload;
// IE always includes the port for the host property of a link
// element, but not in the location.host or origin property for the
// default http port 80 and https port 443, so we strip it:
if (/^(http:\/\/.+:80)|(https:\/\/.+:443)$/.test(target)) {
target = target.replace(/:(80|443)$/, '');
}
return {
send: function (_, completeCallback) {
counter += 1;
var message = {
id: 'postmessage-transport-' + counter
},
eventName = 'message.' + message.id;
iframe = $(
'<iframe style="display:none;" src="' +
options.postMessage + '" name="' +
message.id + '"></iframe>'
).bind('load', function () {
$.each(names, function (i, name) {
message[name] = options[name];
});
message.dataType = message.dataType.replace('postmessage ', '');
$(window).bind(eventName, function (e) {
e = e.originalEvent;
var data = e.data,
ev;
if (e.origin === target && data.id === message.id) {
if (data.type === 'progress') {
ev = document.createEvent('Event');
ev.initEvent(data.type, false, true);
$.extend(ev, data);
xhrUpload.dispatchEvent(ev);
} else {
completeCallback(
data.status,
data.statusText,
{postmessage: data.result},
data.headers
);
iframe.remove();
$(window).unbind(eventName);
}
}
});
iframe[0].contentWindow.postMessage(
message,
target
);
}).appendTo(document.body);
},
abort: function () {
if (iframe) {
iframe.remove();
}
}
};
}
});
}));
/*
* jQuery XDomainRequest Transport Plugin
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2011, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*
* Based on Julian Aubourg's ajaxHooks xdr.js:
* https://github.com/jaubourg/ajaxHooks/
*/
/* global define, require, window, XDomainRequest */
;(function (factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node/CommonJS:
factory(require('jquery'));
} else {
// Browser globals:
factory(window.jQuery);
}
}(function ($) {
'use strict';
if (window.XDomainRequest && !$.support.cors) {
$.ajaxTransport(function (s) {
if (s.crossDomain && s.async) {
if (s.timeout) {
s.xdrTimeout = s.timeout;
delete s.timeout;
}
var xdr;
return {
send: function (headers, completeCallback) {
var addParamChar = /\?/.test(s.url) ? '&' : '?';
function callback(status, statusText, responses, responseHeaders) {
xdr.onload = xdr.onerror = xdr.ontimeout = $.noop;
xdr = null;
completeCallback(status, statusText, responses, responseHeaders);
}
xdr = new XDomainRequest();
// XDomainRequest only supports GET and POST:
if (s.type === 'DELETE') {
s.url = s.url + addParamChar + '_method=DELETE';
s.type = 'POST';
} else if (s.type === 'PUT') {
s.url = s.url + addParamChar + '_method=PUT';
s.type = 'POST';
} else if (s.type === 'PATCH') {
s.url = s.url + addParamChar + '_method=PATCH';
s.type = 'POST';
}
xdr.open(s.type, s.url);
xdr.onload = function () {
callback(
200,
'OK',
{text: xdr.responseText},
'Content-Type: ' + xdr.contentType
);
};
xdr.onerror = function () {
callback(404, 'Not Found');
};
if (s.xdrTimeout) {
xdr.ontimeout = function () {
callback(0, 'timeout');
};
xdr.timeout = s.xdrTimeout;
}
xdr.send((s.hasContent && s.data) || null);
},
abort: function () {
if (xdr) {
xdr.onerror = $.noop();
xdr.abort();
}
}
};
}
});
}
}));
/*
* jQuery File Upload Audio Preview Plugin
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
/* jshint nomen:false */
/* global define, require, window, document */
;(function (factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
define([
'jquery',
'load-image',
'./jquery.fileupload-process'
], factory);
} else if (typeof exports === 'object') {
// Node/CommonJS:
factory(
require('jquery'),
require('blueimp-load-image/js/load-image'),
require('./jquery.fileupload-process')
);
} else {
// Browser globals:
factory(
window.jQuery,
window.loadImage
);
}
}(function ($, loadImage) {
'use strict';
// Prepend to the default processQueue:
$.blueimp.fileupload.prototype.options.processQueue.unshift(
{
action: 'loadAudio',
// Use the action as prefix for the "@" options:
prefix: true,
fileTypes: '@',
maxFileSize: '@',
disabled: '@disableAudioPreview'
},
{
action: 'setAudio',
name: '@audioPreviewName',
disabled: '@disableAudioPreview'
}
);
// The File Upload Audio Preview plugin extends the fileupload widget
// with audio preview functionality:
$.widget('blueimp.fileupload', $.blueimp.fileupload, {
options: {
// The regular expression for the types of audio files to load,
// matched against the file type:
loadAudioFileTypes: /^audio\/.*$/
},
_audioElement: document.createElement('audio'),
processActions: {
// Loads the audio file given via data.files and data.index
// as audio element if the browser supports playing it.
// Accepts the options fileTypes (regular expression)
// and maxFileSize (integer) to limit the files to load:
loadAudio: function (data, options) {
if (options.disabled) {
return data;
}
var file = data.files[data.index],
url,
audio;
if (this._audioElement.canPlayType &&
this._audioElement.canPlayType(file.type) &&
($.type(options.maxFileSize) !== 'number' ||
file.size <= options.maxFileSize) &&
(!options.fileTypes ||
options.fileTypes.test(file.type))) {
url = loadImage.createObjectURL(file);
if (url) {
audio = this._audioElement.cloneNode(false);
audio.src = url;
audio.controls = true;
data.audio = audio;
return data;
}
}
return data;
},
// Sets the audio element as a property of the file object:
setAudio: function (data, options) {
if (data.audio && !options.disabled) {
data.files[data.index][options.name || 'preview'] = data.audio;
}
return data;
}
}
});
}));
This diff is collapsed.
/*
* jQuery File Upload jQuery UI Plugin
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
/* jshint nomen:false */
/* global define, require, window */
;(function (factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
define([
'jquery',
'./jquery.fileupload-ui'
], factory);
} else if (typeof exports === 'object') {
// Node/CommonJS:
factory(
require('jquery'),
require('./jquery.fileupload-ui')
);
} else {
// Browser globals:
factory(window.jQuery);
}
}(function ($) {
'use strict';
$.widget('blueimp.fileupload', $.blueimp.fileupload, {
options: {
processdone: function (e, data) {
data.context.find('.start').button('enable');
},
progress: function (e, data) {
if (data.context) {
data.context.find('.progress').progressbar(
'option',
'value',
parseInt(data.loaded / data.total * 100, 10)
);
}
},
progressall: function (e, data) {
var $this = $(this);
$this.find('.fileupload-progress')
.find('.progress').progressbar(
'option',
'value',
parseInt(data.loaded / data.total * 100, 10)
).end()
.find('.progress-extended').each(function () {
$(this).html(
($this.data('blueimp-fileupload') ||
$this.data('fileupload'))
._renderExtendedProgress(data)
);
});
}
},
_renderUpload: function (func, files) {
var node = this._super(func, files),
showIconText = $(window).width() > 480;
node.find('.progress').empty().progressbar();
node.find('.start').button({
icons: {primary: 'ui-icon-circle-arrow-e'},
text: showIconText
});
node.find('.cancel').button({
icons: {primary: 'ui-icon-cancel'},
text: showIconText
});
if (node.hasClass('fade')) {
node.hide();
}
return node;
},
_renderDownload: function (func, files) {
var node = this._super(func, files),
showIconText = $(window).width() > 480;
node.find('.delete').button({
icons: {primary: 'ui-icon-trash'},
text: showIconText
});
if (node.hasClass('fade')) {
node.hide();
}
return node;
},
_startHandler: function (e) {
$(e.currentTarget).button('disable');
this._super(e);
},
_transition: function (node) {
var deferred = $.Deferred();
if (node.hasClass('fade')) {
node.fadeToggle(
this.options.transitionDuration,
this.options.transitionEasing,
function () {
deferred.resolveWith(node);
}
);
} else {
deferred.resolveWith(node);
}
return deferred;
},
_create: function () {
this._super();
this.element
.find('.fileupload-buttonbar')
.find('.fileinput-button').each(function () {
var input = $(this).find('input:file').detach();
$(this)
.button({icons: {primary: 'ui-icon-plusthick'}})
.append(input);
})
.end().find('.start')
.button({icons: {primary: 'ui-icon-circle-arrow-e'}})
.end().find('.cancel')
.button({icons: {primary: 'ui-icon-cancel'}})
.end().find('.delete')
.button({icons: {primary: 'ui-icon-trash'}})
.end().find('.progress').progressbar();
},
_destroy: function () {
this.element
.find('.fileupload-buttonbar')
.find('.fileinput-button').each(function () {
var input = $(this).find('input:file').detach();
$(this)
.button('destroy')
.append(input);
})
.end().find('.start')
.button('destroy')
.end().find('.cancel')
.button('destroy')
.end().find('.delete')
.button('destroy')
.end().find('.progress').progressbar('destroy');
this._super();
}
});
}));
/*
* jQuery File Upload Processing Plugin
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2012, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
/* jshint nomen:false */
/* global define, require, window */
;(function (factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
define([
'jquery',
'./jquery.fileupload'
], factory);
} else if (typeof exports === 'object') {
// Node/CommonJS:
factory(
require('jquery'),
require('./jquery.fileupload')
);
} else {
// Browser globals:
factory(
window.jQuery
);
}
}(function ($) {
'use strict';
var originalAdd = $.blueimp.fileupload.prototype.options.add;
// The File Upload Processing plugin extends the fileupload widget
// with file processing functionality:
$.widget('blueimp.fileupload', $.blueimp.fileupload, {
options: {
// The list of processing actions:
processQueue: [
/*
{
action: 'log',
type: 'debug'
}
*/
],
add: function (e, data) {
var $this = $(this);
data.process(function () {
return $this.fileupload('process', data);
});
originalAdd.call(this, e, data);
}
},
processActions: {
/*
log: function (data, options) {
console[options.type](
'Processing "' + data.files[data.index].name + '"'
);
}
*/
},
_processFile: function (data, originalData) {
var that = this,
dfd = $.Deferred().resolveWith(that, [data]),
chain = dfd.promise();
this._trigger('process', null, data);
$.each(data.processQueue, function (i, settings) {
var func = function (data) {
if (originalData.errorThrown) {
return $.Deferred()
.rejectWith(that, [originalData]).promise();
}
return that.processActions[settings.action].call(
that,
data,
settings
);
};
chain = chain.then(func, settings.always && func);
});
chain
.done(function () {
that._trigger('processdone', null, data);
that._trigger('processalways', null, data);
})
.fail(function () {
that._trigger('processfail', null, data);
that._trigger('processalways', null, data);
});
return chain;
},
// Replaces the settings of each processQueue item that
// are strings starting with an "@", using the remaining
// substring as key for the option map,
// e.g. "@autoUpload" is replaced with options.autoUpload:
_transformProcessQueue: function (options) {
var processQueue = [];
$.each(options.processQueue, function () {
var settings = {},
action = this.action,
prefix = this.prefix === true ? action : this.prefix;
$.each(this, function (key, value) {
if ($.type(value) === 'string' &&
value.charAt(0) === '@') {
settings[key] = options[
value.slice(1) || (prefix ? prefix +
key.charAt(0).toUpperCase() + key.slice(1) : key)
];
} else {
settings[key] = value;
}
});
processQueue.push(settings);
});
options.processQueue = processQueue;
},
// Returns the number of files currently in the processsing queue:
processing: function () {
return this._processing;
},
// Processes the files given as files property of the data parameter,
// returns a Promise object that allows to bind callbacks:
process: function (data) {
var that = this,
options = $.extend({}, this.options, data);
if (options.processQueue && options.processQueue.length) {
this._transformProcessQueue(options);
if (this._processing === 0) {
this._trigger('processstart');
}
$.each(data.files, function (index) {
var opts = index ? $.extend({}, options) : options,
func = function () {
if (data.errorThrown) {
return $.Deferred()
.rejectWith(that, [data]).promise();
}
return that._processFile(opts, data);
};
opts.index = index;
that._processing += 1;
that._processingQueue = that._processingQueue.then(func, func)
.always(function () {
that._processing -= 1;
if (that._processing === 0) {
that._trigger('processstop');
}
});
});
}
return this._processingQueue;
},
_create: function () {
this._super();
this._processing = 0;
this._processingQueue = $.Deferred().resolveWith(this)
.promise();
}
});
}));
This diff is collapsed.
/*
* jQuery File Upload Validation Plugin
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
/* global define, require, window */
;(function (factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
define([
'jquery',
'./jquery.fileupload-process'
], factory);
} else if (typeof exports === 'object') {
// Node/CommonJS:
factory(
require('jquery'),
require('./jquery.fileupload-process')
);
} else {
// Browser globals:
factory(
window.jQuery
);
}
}(function ($) {
'use strict';
// Append to the default processQueue:
$.blueimp.fileupload.prototype.options.processQueue.push(
{
action: 'validate',
// Always trigger this action,
// even if the previous action was rejected:
always: true,
// Options taken from the global options map:
acceptFileTypes: '@',
maxFileSize: '@',
minFileSize: '@',
maxNumberOfFiles: '@',
disabled: '@disableValidation'
}
);
// The File Upload Validation plugin extends the fileupload widget
// with file validation functionality:
$.widget('blueimp.fileupload', $.blueimp.fileupload, {
options: {
/*
// The regular expression for allowed file types, matches
// against either file type or file name:
acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
// The maximum allowed file size in bytes:
maxFileSize: 10000000, // 10 MB
// The minimum allowed file size in bytes:
minFileSize: undefined, // No minimal file size
// The limit of files to be uploaded:
maxNumberOfFiles: 10,
*/
// Function returning the current number of files,
// has to be overriden for maxNumberOfFiles validation:
getNumberOfFiles: $.noop,
// Error and info messages:
messages: {
maxNumberOfFiles: 'Maximum number of files exceeded',
acceptFileTypes: 'File type not allowed',
maxFileSize: 'File is too large',
minFileSize: 'File is too small'
}
},
processActions: {
validate: function (data, options) {
if (options.disabled) {
return data;
}
var dfd = $.Deferred(),
settings = this.options,
file = data.files[data.index],
fileSize;
if (options.minFileSize || options.maxFileSize) {
fileSize = file.size;
}
if ($.type(options.maxNumberOfFiles) === 'number' &&
(settings.getNumberOfFiles() || 0) + data.files.length >
options.maxNumberOfFiles) {
file.error = settings.i18n('maxNumberOfFiles');
} else if (options.acceptFileTypes &&
!(options.acceptFileTypes.test(file.type) ||
options.acceptFileTypes.test(file.name))) {
file.error = settings.i18n('acceptFileTypes');
} else if (fileSize > options.maxFileSize) {
file.error = settings.i18n('maxFileSize');
} else if ($.type(fileSize) === 'number' &&
fileSize < options.minFileSize) {
file.error = settings.i18n('minFileSize');
} else {
delete file.error;
}
if (file.error || data.files.error) {
data.files.error = true;
dfd.rejectWith(this, [data]);
} else {
dfd.resolveWith(this, [data]);
}
return dfd.promise();
}
}
});
}));
/*
* jQuery File Upload Video Preview Plugin
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
/* jshint nomen:false */
/* global define, require, window, document */
;(function (factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
define([
'jquery',
'load-image',
'./jquery.fileupload-process'
], factory);
} else if (typeof exports === 'object') {
// Node/CommonJS:
factory(
require('jquery'),
require('blueimp-load-image/js/load-image'),
require('./jquery.fileupload-process')
);
} else {
// Browser globals:
factory(
window.jQuery,
window.loadImage
);
}
}(function ($, loadImage) {
'use strict';
// Prepend to the default processQueue:
$.blueimp.fileupload.prototype.options.processQueue.unshift(
{
action: 'loadVideo',
// Use the action as prefix for the "@" options:
prefix: true,
fileTypes: '@',
maxFileSize: '@',
disabled: '@disableVideoPreview'
},
{
action: 'setVideo',
name: '@videoPreviewName',
disabled: '@disableVideoPreview'
}
);
// The File Upload Video Preview plugin extends the fileupload widget
// with video preview functionality:
$.widget('blueimp.fileupload', $.blueimp.fileupload, {
options: {
// The regular expression for the types of video files to load,
// matched against the file type:
loadVideoFileTypes: /^video\/.*$/
},
_videoElement: document.createElement('video'),
processActions: {
// Loads the video file given via data.files and data.index
// as video element if the browser supports playing it.
// Accepts the options fileTypes (regular expression)
// and maxFileSize (integer) to limit the files to load:
loadVideo: function (data, options) {
if (options.disabled) {
return data;
}
var file = data.files[data.index],
url,
video;
if (this._videoElement.canPlayType &&
this._videoElement.canPlayType(file.type) &&
($.type(options.maxFileSize) !== 'number' ||
file.size <= options.maxFileSize) &&
(!options.fileTypes ||
options.fileTypes.test(file.type))) {
url = loadImage.createObjectURL(file);
if (url) {
video = this._videoElement.cloneNode(false);
video.src = url;
video.controls = true;
data.video = video;
return data;
}
}
return data;
},
// Sets the video element as a property of the file object:
setVideo: function (data, options) {
if (data.video && !options.disabled) {
data.files[data.index][options.name || 'preview'] = data.video;
}
return data;
}
}
});
}));
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* jQuery File Upload Plugin JS Example
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2010, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
/* global $, window */
$(function () {
'use strict';
// Initialize the jQuery File Upload widget:
$('#fileupload').fileupload({
// Uncomment the following to send cross-domain cookies:
//xhrFields: {withCredentials: true},
url: 'server/php/'
});
// Enable iframe cross-domain access via redirect option:
$('#fileupload').fileupload(
'option',
'redirect',
window.location.href.replace(
/\/[^\/]*$/,
'/cors/result.html?%s'
)
);
if (window.location.hostname === 'blueimp.github.io') {
// Demo settings:
$('#fileupload').fileupload('option', {
url: '//jquery-file-upload.appspot.com/',
// Enable image resizing, except for Android and Opera,
// which actually support image resizing, but fail to
// send Blob objects via XHR requests:
disableImageResize: /Android(?!.*Chrome)|Opera/
.test(window.navigator.userAgent),
maxFileSize: 999000,
acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i
});
// Upload server status check for browsers with CORS support:
if ($.support.cors) {
$.ajax({
url: '//jquery-file-upload.appspot.com/',
type: 'HEAD'
}).fail(function () {
$('<div class="alert alert-danger"/>')
.text('Upload server currently unavailable - ' +
new Date())
.appendTo('#fileupload');
});
}
} else {
// Load existing files:
$('#fileupload').addClass('fileupload-processing');
$.ajax({
// Uncomment the following to send cross-domain cookies:
//xhrFields: {withCredentials: true},
url: $('#fileupload').fileupload('option', 'url'),
dataType: 'json',
context: $('#fileupload')[0]
}).always(function () {
$(this).removeClass('fileupload-processing');
}).done(function (result) {
$(this).fileupload('option', 'done')
.call(this, $.Event('done'), {result: result});
});
}
});
This diff is collapsed.
{
"name": "blueimp-file-upload",
"version": "9.21.0",
"title": "jQuery File Upload",
"description": "File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads. Works with any server-side platform (Google App Engine, PHP, Python, Ruby on Rails, Java, etc.) that supports standard HTML form file uploads.",
"keywords": [
"jquery",
"file",
"upload",
"widget",
"multiple",
"selection",
"drag",
"drop",
"progress",
"preview",
"cross-domain",
"cross-site",
"chunk",
"resume",
"gae",
"go",
"python",
"php",
"bootstrap"
],
"homepage": "https://github.com/blueimp/jQuery-File-Upload",
"author": {
"name": "Sebastian Tschan",
"url": "https://blueimp.net"
},
"repository": {
"type": "git",
"url": "git://github.com/blueimp/jQuery-File-Upload.git"
},
"license": "MIT",
"optionalDependencies": {
"blueimp-canvas-to-blob": "3.5.0",
"blueimp-load-image": "2.12.2",
"blueimp-tmpl": "3.6.0"
},
"devDependencies": {
"bower-json": "0.8.1",
"jshint": "2.9.3"
},
"scripts": {
"bower-version-update": "./bower-version-update.js",
"lint": "jshint *.js js/*.js js/cors/*.js",
"test": "npm run lint",
"preversion": "npm test",
"version": "npm run bower-version-update && git add bower.json",
"postversion": "git push --tags origin master && npm publish"
},
"main": "js/jquery.fileupload.js"
}
application: jquery-file-upload
version: 2
runtime: go
api_version: go1
handlers:
- url: /(favicon\.ico|robots\.txt)
static_files: static/\1
upload: static/(.*)
expiration: '1d'
- url: /.*
script: _go_app
This diff is collapsed.
application: jquery-file-upload
version: 1
runtime: python27
api_version: 1
threadsafe: true
libraries:
- name: PIL
version: latest
handlers:
- url: /(favicon\.ico|robots\.txt)
static_files: static/\1
upload: static/(.*)
expiration: '1d'
- url: /.*
script: main.app
# -*- coding: utf-8 -*-
#
# jQuery File Upload Plugin GAE Python Example
# https://github.com/blueimp/jQuery-File-Upload
#
# Copyright 2011, Sebastian Tschan
# https://blueimp.net
#
# Licensed under the MIT license:
# https://opensource.org/licenses/MIT
#
from google.appengine.api import memcache, images
import json
import os
import re
import urllib
import webapp2
DEBUG=os.environ.get('SERVER_SOFTWARE', '').startswith('Dev')
WEBSITE = 'https://blueimp.github.io/jQuery-File-Upload/'
MIN_FILE_SIZE = 1 # bytes
# Max file size is memcache limit (1MB) minus key size minus overhead:
MAX_FILE_SIZE = 999000 # bytes
IMAGE_TYPES = re.compile('image/(gif|p?jpeg|(x-)?png)')
ACCEPT_FILE_TYPES = IMAGE_TYPES
THUMB_MAX_WIDTH = 80
THUMB_MAX_HEIGHT = 80
THUMB_SUFFIX = '.'+str(THUMB_MAX_WIDTH)+'x'+str(THUMB_MAX_HEIGHT)+'.png'
EXPIRATION_TIME = 300 # seconds
# If set to None, only allow redirects to the referer protocol+host.
# Set to a regexp for custom pattern matching against the redirect value:
REDIRECT_ALLOW_TARGET = None
class CORSHandler(webapp2.RequestHandler):
def cors(self):
headers = self.response.headers
headers['Access-Control-Allow-Origin'] = '*'
headers['Access-Control-Allow-Methods'] =\
'OPTIONS, HEAD, GET, POST, DELETE'
headers['Access-Control-Allow-Headers'] =\
'Content-Type, Content-Range, Content-Disposition'
def initialize(self, request, response):
super(CORSHandler, self).initialize(request, response)
self.cors()
def json_stringify(self, obj):
return json.dumps(obj, separators=(',', ':'))
def options(self, *args, **kwargs):
pass
class UploadHandler(CORSHandler):
def validate(self, file):
if file['size'] < MIN_FILE_SIZE:
file['error'] = 'File is too small'
elif file['size'] > MAX_FILE_SIZE:
file['error'] = 'File is too big'
elif not ACCEPT_FILE_TYPES.match(file['type']):
file['error'] = 'Filetype not allowed'
else:
return True
return False
def validate_redirect(self, redirect):
if redirect:
if REDIRECT_ALLOW_TARGET:
return REDIRECT_ALLOW_TARGET.match(redirect)
referer = self.request.headers['referer']
if referer:
from urlparse import urlparse
parts = urlparse(referer)
redirect_allow_target = '^' + re.escape(
parts.scheme + '://' + parts.netloc + '/'
)
return re.match(redirect_allow_target, redirect)
return False
def get_file_size(self, file):
file.seek(0, 2) # Seek to the end of the file
size = file.tell() # Get the position of EOF
file.seek(0) # Reset the file position to the beginning
return size
def write_blob(self, data, info):
key = urllib.quote(info['type'].encode('utf-8'), '') +\
'/' + str(hash(data)) +\
'/' + urllib.quote(info['name'].encode('utf-8'), '')
try:
memcache.set(key, data, time=EXPIRATION_TIME)
except: #Failed to add to memcache
return (None, None)
thumbnail_key = None
if IMAGE_TYPES.match(info['type']):
try:
img = images.Image(image_data=data)
img.resize(
width=THUMB_MAX_WIDTH,
height=THUMB_MAX_HEIGHT
)
thumbnail_data = img.execute_transforms()
thumbnail_key = key + THUMB_SUFFIX
memcache.set(
thumbnail_key,
thumbnail_data,
time=EXPIRATION_TIME
)
except: #Failed to resize Image or add to memcache
thumbnail_key = None
return (key, thumbnail_key)
def handle_upload(self):
results = []
for name, fieldStorage in self.request.POST.items():
if type(fieldStorage) is unicode:
continue
result = {}
result['name'] = urllib.unquote(fieldStorage.filename)
result['type'] = fieldStorage.type
result['size'] = self.get_file_size(fieldStorage.file)
if self.validate(result):
key, thumbnail_key = self.write_blob(
fieldStorage.value,
result
)
if key is not None:
result['url'] = self.request.host_url + '/' + key
result['deleteUrl'] = result['url']
result['deleteType'] = 'DELETE'
if thumbnail_key is not None:
result['thumbnailUrl'] = self.request.host_url +\
'/' + thumbnail_key
else:
result['error'] = 'Failed to store uploaded file.'
results.append(result)
return results
def head(self):
pass
def get(self):
self.redirect(WEBSITE)
def post(self):
if (self.request.get('_method') == 'DELETE'):
return self.delete()
result = {'files': self.handle_upload()}
s = self.json_stringify(result)
redirect = self.request.get('redirect')
if self.validate_redirect(redirect):
return self.redirect(str(
redirect.replace('%s', urllib.quote(s, ''), 1)
))
if 'application/json' in self.request.headers.get('Accept'):
self.response.headers['Content-Type'] = 'application/json'
self.response.write(s)
class FileHandler(CORSHandler):
def normalize(self, str):
return urllib.quote(urllib.unquote(str), '')
def get(self, content_type, data_hash, file_name):
content_type = self.normalize(content_type)
file_name = self.normalize(file_name)
key = content_type + '/' + data_hash + '/' + file_name
data = memcache.get(key)
if data is None:
return self.error(404)
# Prevent browsers from MIME-sniffing the content-type:
self.response.headers['X-Content-Type-Options'] = 'nosniff'
content_type = urllib.unquote(content_type)
if not IMAGE_TYPES.match(content_type):
# Force a download dialog for non-image types:
content_type = 'application/octet-stream'
elif file_name.endswith(THUMB_SUFFIX):
content_type = 'image/png'
self.response.headers['Content-Type'] = content_type
# Cache for the expiration time:
self.response.headers['Cache-Control'] = 'public,max-age=%d' \
% EXPIRATION_TIME
self.response.write(data)
def delete(self, content_type, data_hash, file_name):
content_type = self.normalize(content_type)
file_name = self.normalize(file_name)
key = content_type + '/' + data_hash + '/' + file_name
result = {key: memcache.delete(key)}
content_type = urllib.unquote(content_type)
if IMAGE_TYPES.match(content_type):
thumbnail_key = key + THUMB_SUFFIX
result[thumbnail_key] = memcache.delete(thumbnail_key)
if 'application/json' in self.request.headers.get('Accept'):
self.response.headers['Content-Type'] = 'application/json'
s = self.json_stringify(result)
self.response.write(s)
app = webapp2.WSGIApplication(
[
('/', UploadHandler),
('/(.+)/([^/]+)/([^/]+)', FileHandler)
],
debug=DEBUG
)
FROM php:7-apache
# Enable the Apache Headers module:
RUN ln -s /etc/apache2/mods-available/headers.load \
/etc/apache2/mods-enabled/headers.load
# Enable the Apache Rewrite module:
RUN ln -s /etc/apache2/mods-available/rewrite.load \
/etc/apache2/mods-enabled/rewrite.load
# Install GD, Imagick and ImageMagick as image conversion options:
RUN DEBIAN_FRONTEND=noninteractive \
apt-get update && apt-get install -y --no-install-recommends \
libpng-dev \
libjpeg-dev \
libmagickwand-dev \
imagemagick \
&& pecl install \
imagick \
&& docker-php-ext-enable \
imagick \
&& docker-php-ext-configure \
gd --with-jpeg-dir=/usr/include/ \
&& docker-php-ext-install \
gd \
# Uninstall obsolete packages:
&& apt-get autoremove -y \
libpng-dev \
libjpeg-dev \
libmagickwand-dev \
# Remove obsolete files:
&& apt-get clean \
&& rm -rf \
/tmp/* \
/usr/share/doc/* \
/var/cache/* \
/var/lib/apt/lists/* \
/var/tmp/*
This diff is collapsed.
version: '2.3'
services:
apache:
build: ./
network_mode: bridge
ports:
- "80:80"
volumes:
- "../../:/var/www/html"
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment