First commit of fileupload packaging

This commit is contained in:
Jordan OMara 2014-09-09 09:26:20 -04:00
commit ccdc04b8af
7 changed files with 349 additions and 0 deletions

8
MANIFEST.in Normal file
View File

@ -0,0 +1,8 @@
include README.txt
recursive-include xstatic/pkg/angular_fileupload *
global-exclude *.pyc
global-exclude *.pyo
global-exclude *.orig
global-exclude *.rej

13
README.txt Normal file
View File

@ -0,0 +1,13 @@
XStatic-Angular-Filepload
-------------------------
Angular-FileUpload JavaScript library packaged for setuptools (easy_install) / pip.
This package is intended to be used by **any** project that needs these files.
It intentionally does **not** provide any extra code except some metadata
**nor** has any extra requirements. You MAY use some minimal support code from
the XStatic base package, if you like.
You can find more info about the xstatic packaging way in the package `XStatic`.

27
setup.py Normal file
View File

@ -0,0 +1,27 @@
from xstatic.pkg import angular_fileupload as xs
# The README.txt file should be written in reST so that PyPI can use
# it to generate your project's PyPI page.
long_description = open('README.txt').read()
from setuptools import setup, find_packages
setup(
name=xs.PACKAGE_NAME,
version=xs.PACKAGE_VERSION,
description=xs.DESCRIPTION,
long_description=long_description,
classifiers=xs.CLASSIFIERS,
keywords=xs.KEYWORDS,
maintainer=xs.MAINTAINER,
maintainer_email=xs.MAINTAINER_EMAIL,
license=xs.LICENSE,
url=xs.HOMEPAGE,
platforms=xs.PLATFORMS,
packages=find_packages(),
namespace_packages=['xstatic', 'xstatic.pkg', ],
include_package_data=True,
zip_safe=False,
install_requires=[], # nothing! :)
# if you like, you MAY use the 'XStatic' package.
)

1
xstatic/__init__.py Normal file
View File

@ -0,0 +1 @@
__import__('pkg_resources').declare_namespace(__name__)

1
xstatic/pkg/__init__.py Normal file
View File

@ -0,0 +1 @@
__import__('pkg_resources').declare_namespace(__name__)

View File

@ -0,0 +1,49 @@
"""
XStatic resource package
See package 'XStatic' for documentation and basic tools.
"""
DISPLAY_NAME = 'Angular-Bootstrap' # official name, upper/lowercase allowed, no spaces
PACKAGE_NAME = 'XStatic-%s' % DISPLAY_NAME # name used for PyPi
NAME = __name__.split('.')[-1] # package name (e.g. 'foo' or 'foo_bar')
# please use a all-lowercase valid python
# package name
VERSION = '0.11.0' # version of the packaged files, please use the upstream
# version number
BUILD = '2' # our package build number, so we can release new builds
# with fixes for xstatic stuff.
PACKAGE_VERSION = VERSION + '.' + BUILD # version used for PyPi
DESCRIPTION = "%s %s (XStatic packaging standard)" % (DISPLAY_NAME, VERSION)
PLATFORMS = 'any'
CLASSIFIERS = []
KEYWORDS = '%s xstatic' % NAME
# XStatic-* package maintainer:
MAINTAINER = 'Jordan OMara'
MAINTAINER_EMAIL = 'jsomara@gmail.com'
# this refers to the project homepage of the stuff we packaged:
HOMEPAGE = 'https://github.com/danialfarid/angular-file-upload'
# this refers to all files:
LICENSE = '(same as %s)' % DISPLAY_NAME
from os.path import join, dirname
BASE_DIR = join(dirname(__file__), 'data')
# linux package maintainers just can point to their file locations like this:
#BASE_DIR = '/usr/share/javascript/angular_cookies'
LOCATIONS = {
# CDN locations (if no public CDN exists, use an empty dict)
# if value is a string, it is a base location, just append relative
# path/filename. if value is a dict, do another lookup using the
# relative path/filename you want.
# your relative path/filenames should usually be without version
# information, because either the base dir/url is exactly for this
# version or the mapping will care for accessing this version.
}

View File

@ -0,0 +1,250 @@
/**!
* AngularJS file upload/drop directive with http post and progress
* @author Danial <danial.farid@gmail.com>
* @version 1.4.0
*/
(function() {
var angularFileUpload = angular.module('angularFileUpload', []);
angularFileUpload.service('$upload', ['$http', '$timeout', function($http, $timeout) {
function sendHttp(config) {
config.method = config.method || 'POST';
config.headers = config.headers || {};
config.transformRequest = config.transformRequest || function(data, headersGetter) {
if (window.ArrayBuffer && data instanceof window.ArrayBuffer) {
return data;
}
return $http.defaults.transformRequest[0](data, headersGetter);
};
if (window.XMLHttpRequest.__isShim) {
config.headers['__setXHR_'] = function() {
return function(xhr) {
if (!xhr) return;
config.__XHR = xhr;
config.xhrFn && config.xhrFn(xhr);
xhr.upload.addEventListener('progress', function(e) {
if (config.progress) {
$timeout(function() {
if(config.progress) config.progress(e);
});
}
}, false);
//fix for firefox not firing upload progress end, also IE8-9
xhr.upload.addEventListener('load', function(e) {
if (e.lengthComputable) {
if(config.progress) config.progress(e);
}
}, false);
};
};
}
var promise = $http(config);
promise.progress = function(fn) {
config.progress = fn;
return promise;
};
promise.abort = function() {
if (config.__XHR) {
$timeout(function() {
config.__XHR.abort();
});
}
return promise;
};
promise.xhr = function(fn) {
config.xhrFn = fn;
return promise;
};
promise.then = (function(promise, origThen) {
return function(s, e, p) {
config.progress = p || config.progress;
var result = origThen.apply(promise, [s, e, p]);
result.abort = promise.abort;
result.progress = promise.progress;
result.xhr = promise.xhr;
result.then = promise.then;
return result;
};
})(promise, promise.then);
return promise;
}
this.upload = function(config) {
config.headers = config.headers || {};
config.headers['Content-Type'] = undefined;
config.transformRequest = config.transformRequest || $http.defaults.transformRequest;
var formData = new FormData();
var origTransformRequest = config.transformRequest;
var origData = config.data;
config.transformRequest = function(formData, headerGetter) {
if (origData) {
if (config.formDataAppender) {
for (var key in origData) {
var val = origData[key];
config.formDataAppender(formData, key, val);
}
} else {
for (var key in origData) {
var val = origData[key];
if (typeof origTransformRequest == 'function') {
val = origTransformRequest(val, headerGetter);
} else {
for (var i = 0; i < origTransformRequest.length; i++) {
var transformFn = origTransformRequest[i];
if (typeof transformFn == 'function') {
val = transformFn(val, headerGetter);
}
}
}
formData.append(key, val);
}
}
}
if (config.file != null) {
var fileFormName = config.fileFormDataName || 'file';
if (Object.prototype.toString.call(config.file) === '[object Array]') {
var isFileFormNameString = Object.prototype.toString.call(fileFormName) === '[object String]';
for (var i = 0; i < config.file.length; i++) {
formData.append(isFileFormNameString ? fileFormName + i : fileFormName[i], config.file[i], config.file[i].name);
}
} else {
formData.append(fileFormName, config.file, config.file.name);
}
}
return formData;
};
config.data = formData;
return sendHttp(config);
};
this.http = function(config) {
return sendHttp(config);
}
}]);
angularFileUpload.directive('ngFileSelect', [ '$parse', '$timeout', function($parse, $timeout) {
return function(scope, elem, attr) {
var fn = $parse(attr['ngFileSelect']);
elem.bind('change', function(evt) {
var files = [], fileList, i;
fileList = evt.target.files;
if (fileList != null) {
for (i = 0; i < fileList.length; i++) {
files.push(fileList.item(i));
}
}
$timeout(function() {
fn(scope, {
$files : files,
$event : evt
});
});
});
// removed this since it was confusing if the user click on browse and then cancel #181
// elem.bind('click', function(){
// this.value = null;
// });
// touch screens
if (('ontouchstart' in window) ||
(navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0)) {
elem.bind('touchend', function(e) {
e.preventDefault();
e.target.click();
});
}
};
} ]);
angularFileUpload.directive('ngFileDropAvailable', [ '$parse', '$timeout', function($parse, $timeout) {
return function(scope, elem, attr) {
if ('draggable' in document.createElement('span')) {
var fn = $parse(attr['ngFileDropAvailable']);
$timeout(function() {
fn(scope);
});
}
};
} ]);
angularFileUpload.directive('ngFileDrop', [ '$parse', '$timeout', function($parse, $timeout) {
return function(scope, elem, attr) {
if ('draggable' in document.createElement('span')) {
var cancel = null;
var fn = $parse(attr['ngFileDrop']);
elem[0].addEventListener("dragover", function(evt) {
$timeout.cancel(cancel);
evt.stopPropagation();
evt.preventDefault();
elem.addClass(attr['ngFileDragOverClass'] || "dragover");
}, false);
elem[0].addEventListener("dragleave", function(evt) {
cancel = $timeout(function() {
elem.removeClass(attr['ngFileDragOverClass'] || "dragover");
});
}, false);
var processing = 0;
function traverseFileTree(files, item) {
if (item.isDirectory) {
var dirReader = item.createReader();
processing++;
dirReader.readEntries(function(entries) {
for (var i = 0; i < entries.length; i++) {
traverseFileTree(files, entries[i]);
}
processing--;
});
} else {
processing++;
item.file(function(file) {
processing--;
files.push(file);
});
}
}
elem[0].addEventListener("drop", function(evt) {
evt.stopPropagation();
evt.preventDefault();
elem.removeClass(attr['ngFileDragOverClass'] || "dragover");
var files = [], items = evt.dataTransfer.items;
if (items && items.length > 0 && items[0].webkitGetAsEntry) {
for (var i = 0; i < items.length; i++) {
traverseFileTree(files, items[i].webkitGetAsEntry());
}
} else {
var fileList = evt.dataTransfer.files;
if (fileList != null) {
for (var i = 0; i < fileList.length; i++) {
files.push(fileList.item(i));
}
}
}
(function callback(delay) {
$timeout(function() {
if (!processing) {
fn(scope, {
$files : files,
$event : evt
});
} else {
callback(10);
}
}, delay || 0)
})();
}, false);
}
};
} ]);
})();