From 386a1c08f4b31fe7d706acf6443a53a7c379e3f6 Mon Sep 17 00:00:00 2001 From: Jason Kraus Date: Mon, 27 Feb 2012 17:01:53 -0800 Subject: [PATCH] initial commit of django-uploadify --- .gitignore | 3 + LICENSE | 24 + MANIFEST.in | 1 + directupload/__init__.py | 0 directupload/admin.py | 17 + directupload/app_settings.py | 5 + directupload/backends/__init__.py | 11 + directupload/backends/base.py | 61 ++ directupload/backends/common.py | 11 + directupload/backends/djangoview.py | 31 + directupload/backends/s3.py | 99 +++ directupload/backends/utils.py | 44 ++ directupload/models.py | 11 + .../static/uploadify/jquery.uploadify.js | 677 ++++++++++++++++++ .../static/uploadify/jquery.uploadify.min.js | 38 + .../static/uploadify/uploadify-cancel.png | Bin 0 -> 2960 bytes directupload/static/uploadify/uploadify.css | 72 ++ directupload/static/uploadify/uploadify.swf | Bin 0 -> 12787 bytes directupload/static/uploadify/widget.js | 127 ++++ .../templates/admin/includes/fieldset.html | 36 + .../uploadify/templatetags/head.html | 9 + .../templatetags/render_uploadify_widget.html | 1 + directupload/templatetags/__init__.py | 0 directupload/templatetags/uploadify_tags.py | 49 ++ directupload/urls.py | 8 + directupload/views.py | 44 ++ directupload/widgets.py | 69 ++ setup.py | 27 + 28 files changed, 1475 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 MANIFEST.in create mode 100644 directupload/__init__.py create mode 100644 directupload/admin.py create mode 100644 directupload/app_settings.py create mode 100644 directupload/backends/__init__.py create mode 100644 directupload/backends/base.py create mode 100644 directupload/backends/common.py create mode 100644 directupload/backends/djangoview.py create mode 100644 directupload/backends/s3.py create mode 100644 directupload/backends/utils.py create mode 100644 directupload/models.py create mode 100644 directupload/static/uploadify/jquery.uploadify.js create mode 100644 directupload/static/uploadify/jquery.uploadify.min.js create mode 100644 directupload/static/uploadify/uploadify-cancel.png create mode 100644 directupload/static/uploadify/uploadify.css create mode 100644 directupload/static/uploadify/uploadify.swf create mode 100644 directupload/static/uploadify/widget.js create mode 100644 directupload/templates/admin/includes/fieldset.html create mode 100644 directupload/templates/uploadify/templatetags/head.html create mode 100644 directupload/templates/uploadify/templatetags/render_uploadify_widget.html create mode 100644 directupload/templatetags/__init__.py create mode 100644 directupload/templatetags/uploadify_tags.py create mode 100644 directupload/urls.py create mode 100644 directupload/views.py create mode 100644 directupload/widgets.py create mode 100644 setup.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d8f2f28 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.py[cdo] +*~ + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..20f65e7 --- /dev/null +++ b/LICENSE @@ -0,0 +1,24 @@ +Copyright (c) 2012, Cuker Interactive +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the author nor the names of other contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..9c2c806 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1 @@ +recursive-include directupload/templates * diff --git a/directupload/__init__.py b/directupload/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/directupload/admin.py b/directupload/admin.py new file mode 100644 index 0000000..b957c3c --- /dev/null +++ b/directupload/admin.py @@ -0,0 +1,17 @@ +from django.db import models +from django.contrib.admin import ModelAdmin + +from widgets import UploadifyClearableFileInput + +class UploadifyAdminMixin(object): + def formfield_for_dbfield(self, db_field, **kwargs): + if isinstance(db_field, models.FileField): + return self.formfield_for_file_field(db_field, kwargs.pop('request', None), **kwargs) + return ModelAdmin.formfield_for_dbfield(self, db_field, **kwargs) + + def formfield_for_file_field(self, db_field, request=None, **kwargs): + """ + Get a form Field that is prepared for uploadify + """ + kwargs['widget'] = UploadifyClearableFileInput(db_field=db_field) + return db_field.formfield(**kwargs) diff --git a/directupload/app_settings.py b/directupload/app_settings.py new file mode 100644 index 0000000..90a234e --- /dev/null +++ b/directupload/app_settings.py @@ -0,0 +1,5 @@ +from django.conf import settings + +UPLOADIFY_BACKEND = getattr(settings, 'UPLOADIFY_BACKEND', 'directupload.backends.djangoview.DjangoViewBackend') +#UPLOADIFY_BACKEND = getattr(settings, 'UPLOADIFY_BACKEND', 'directupload.backends.s3.S3UploadifyBackend') + diff --git a/directupload/backends/__init__.py b/directupload/backends/__init__.py new file mode 100644 index 0000000..68ee5f5 --- /dev/null +++ b/directupload/backends/__init__.py @@ -0,0 +1,11 @@ +try: + import importlib +except ImportError: + from django.utils import importlib + +def get_uploadify_backend(): + from directupload.app_settings import UPLOADIFY_BACKEND + module_name, class_name = UPLOADIFY_BACKEND.rsplit('.', 1) + module = importlib.import_module(module_name) + return getattr(module, class_name) + diff --git a/directupload/backends/base.py b/directupload/backends/base.py new file mode 100644 index 0000000..660a25e --- /dev/null +++ b/directupload/backends/base.py @@ -0,0 +1,61 @@ +from django.conf import settings +from django.core.exceptions import ImproperlyConfigured +from django.core.urlresolvers import reverse + +from django.utils import simplejson as json + +from common import UPLOADIFY_OPTIONS, UPLOADIFY_METHODS, DEFAULT_CANCELIMG, DEFAULT_UPLOADER, BUTTON_TEXT + +class BaseUploadifyBackend(object): + def __init__(self, request, uploadify_options={}, post_data={}): + self.request = request + self.options = getattr(settings, 'UPLOADIFY_DEFAULT_OPTIONS', {}) + self.options.update(uploadify_options) + + if any(True for key in self.options if key not in UPLOADIFY_OPTIONS + UPLOADIFY_METHODS): + raise ImproperlyConfigured("Attempted to initialize with unrecognized option '%s'." % key) + + _set_default_if_none(self.options, 'cancelImage', DEFAULT_CANCELIMG) + _set_default_if_none(self.options, 'swf', DEFAULT_UPLOADER) + _set_default_if_none(self.options, 'uploader', self.get_uploader()) + _set_default_if_none(self.options, 'buttonText', BUTTON_TEXT) + _set_default_if_none(self.options, 'checkExisting', self.get_check_existing()) + _set_default_if_none(self.options, 'determineName', self.get_determine_name()) + + self.post_data = post_data + self.build_post_data() + + def get_check_existing(self): + return False + + def get_determine_name(self): + return reverse('uploadify-determine-name') + + def get_uploader(self): + pass + + def build_post_data(self): + pass + + def update_post_params(self, params): + pass + + def get_options_json(self): + self.options['postData'] = self.post_data + subs = [] + for key in self.options: + if key in UPLOADIFY_METHODS: + subs.append(('"%%%s%%"' % key, self.options[key])) + self.options[key] = "%%%s%%" % key + + out = json.dumps(self.options) + + for search, replace in subs: + out = out.replace(search, replace) + + return out + +def _set_default_if_none(dict, key, default=None): + if key not in dict: + dict[key] = default + diff --git a/directupload/backends/common.py b/directupload/backends/common.py new file mode 100644 index 0000000..5010b55 --- /dev/null +++ b/directupload/backends/common.py @@ -0,0 +1,11 @@ +from django.conf import settings + +UPLOADIFY_OPTIONS = ('auto', 'buttonImg', 'buttonText', 'cancelImg', 'checkScript', 'displayData', 'expressInstall', 'fileDataName', 'fileDesc', 'fileExt', 'folder', 'height', 'hideButton', 'method', 'multi', 'queueID', 'queueSizeLimit', 'removeCompleted', 'rollover', 'script','scriptAccess', 'scriptData', 'simUploadLimit', 'sizeLimit', 'uploader', 'width', 'wmode') + +UPLOADIFY_METHODS = ('onAllComplete', 'onCancel', 'onCheck', 'onClearQueue', 'onComplete', 'onError', 'onInit', 'onOpen', 'onProgress', 'onQueueFull', 'onSelect', 'onSelectOnce', 'onSWFReady') + +BUTTON_TEXT = 'Select File' + +# Defaults for required Uploadify options +DEFAULT_CANCELIMG = settings.STATIC_URL + "uploadify/uploadify-cancel.png" +DEFAULT_UPLOADER = settings.STATIC_URL + "uploadify/uploadify.swf" diff --git a/directupload/backends/djangoview.py b/directupload/backends/djangoview.py new file mode 100644 index 0000000..33b970c --- /dev/null +++ b/directupload/backends/djangoview.py @@ -0,0 +1,31 @@ +from base import BaseUploadifyBackend + +import datetime +from urllib import urlencode + +from django.middleware.csrf import get_token +from django.core.urlresolvers import reverse + +from utils import Signer +signer = Signer() + +def sign(value): + return signer.sign(value) + +def unsign(value): + return signer.unsign(value) + +class DjangoViewBackend(BaseUploadifyBackend): + """Uploadify for using the builtin django view""" + + def get_uploader(self): + return reverse('uploadify-upload-file') + + def build_post_data(self): + data = {'upload_to': self.options['folder'], + 'request_time': datetime.datetime.now().isoformat(), + '_request_id': 'foo',} #TODO salt} + signed_data = sign(urlencode(data)) + self.post_data['payload'] = signed_data + self.post_data['csrfmiddlewaretoken'] = get_token(self.request) + diff --git a/directupload/backends/s3.py b/directupload/backends/s3.py new file mode 100644 index 0000000..0df4db3 --- /dev/null +++ b/directupload/backends/s3.py @@ -0,0 +1,99 @@ +from django.conf import settings +from django.core.exceptions import ImproperlyConfigured +from urllib import quote_plus +from datetime import datetime +from datetime import timedelta +import base64 +import hmac +import hashlib +import os + +from base import BaseUploadifyBackend, _set_default_if_none, json + +# AWS Options +ACCESS_KEY_ID = getattr(settings, 'AWS_ACCESS_KEY_ID', None) +SECRET_ACCESS_KEY = getattr(settings, 'AWS_SECRET_ACCESS_KEY', None) +BUCKET_NAME = getattr(settings, 'AWS_BUCKET_NAME', None) +SECURE_URLS = getattr(settings, 'AWS_S3_SECURE_URLS', False) +BUCKET_URL = getattr(settings, 'AWS_BUCKET_URL', ('https://' if SECURE_URLS else 'http://') + BUCKET_NAME + '.s3.amazonaws.com') +DEFAULT_ACL = getattr(settings, 'AWS_DEFAULT_ACL', 'public-read') +DEFAULT_KEY_PATTERN = getattr(settings, 'AWS_DEFAULT_KEY_PATTERN', '${targetname}') +DEFAULT_FORM_TIME = getattr(settings, 'AWS_DEFAULT_FORM_LIFETIME', 36000) # 10 HOURS + + +class S3UploadifyBackend(BaseUploadifyBackend): + """Uploadify for Amazon S3""" + + def __init__(self, request, uploadify_options={}, post_data={}, conditions={}): + self.conditions = conditions + super(S3UploadifyBackend, self).__init__(request, uploadify_options, post_data) + + def get_uploader(self): + return BUCKET_URL + + def build_post_data(self): + self.options['fileObjName'] = 'file' #S3 requires this be the field name + + if 'folder' in self.options: + key = os.path.join(self.options['folder'], DEFAULT_KEY_PATTERN) + else: + key = DEFAULT_KEY_PATTERN + #_set_default_if_none(self.post_data, 'key', key) #this is set by update_post_params + _set_default_if_none(self.post_data, 'acl', DEFAULT_ACL) + + try: + _set_default_if_none(self.post_data, 'bucket', BUCKET_NAME) + except ValueError: + raise ImproperlyConfigured("Bucket name is a required property.") + + try: + _set_default_if_none(self.post_data, 'AWSAccessKeyId', ACCESS_KEY_ID) + except ValueError: + raise ImproperlyConfigured("AWS Access Key ID is a required property.") + + self.conditions = self.build_conditions() + + if not SECRET_ACCESS_KEY: + raise ImproperlyConfigured("AWS Secret Access Key is a required property.") + + expiration_time = datetime.utcnow() + timedelta(seconds=DEFAULT_FORM_TIME) + self.policy_string = self.build_post_policy(expiration_time) + self.policy = base64.b64encode(self.policy_string) + + self.signature = base64.encodestring(hmac.new(SECRET_ACCESS_KEY, self.policy, hashlib.sha1).digest()).strip() + + self.post_data['policy'] = self.policy + self.post_data['signature'] = self.signature + + def build_conditions(self): + conditions = list() + + #make s3 happy with uploadify + #conditions.append(['starts-with', '$folder', '']) #no longer passed by uploadify + conditions.append(['starts-with', '$filename', '']) + conditions.append(['starts-with', '$targetname', '']) #variable introduced by this package + conditions.append(['starts-with', '$targetpath', self.options['folder']]) + #conditions.append({'success_action_status': '200'}) + + #real conditions + conditions.append(['starts-with', '$key', self.options['folder']]) + conditions.append({'bucket': self.post_data['bucket']}) + conditions.append({'acl': self.post_data['acl']}) + return conditions + + def build_post_policy(self, expiration_time): + policy = {'expiration': expiration_time.strftime("%Y-%m-%dT%H:%M:%SZ"), + 'conditions': self.conditions,} + return json.dumps(policy) + + def update_post_params(self, params): + #instruct s3 that our key is the targetpath + params['key'] = params['targetpath'] + +def _uri_encode(str): + try: + # The Uploadify flash component apparently decodes the scriptData once, so we need to encode twice here. + return quote_plus(quote_plus(str, safe='~'), safe='~') + except: + raise ValueError + diff --git a/directupload/backends/utils.py b/directupload/backends/utils.py new file mode 100644 index 0000000..82409cd --- /dev/null +++ b/directupload/backends/utils.py @@ -0,0 +1,44 @@ +from django.conf import settings +from django.utils.crypto import constant_time_compare, salted_hmac + +import base64 + +def b64_encode(s): + return base64.urlsafe_b64encode(s).strip('=') + +def b64_decode(s): + pad = '=' * (-len(s) % 4) + return base64.urlsafe_b64decode(s + pad) + +def base64_hmac(salt, value, key): + return b64_encode(salted_hmac(salt, value, key).digest()) + +class LegacySigner(object): + ''' + Limited functionality signer + ''' + def __init__(self, key=None, sep=':', salt=None): + self.sep = sep + self.key = key or settings.SECRET_KEY + self.salt = salt or ('%s.%s' % + (self.__class__.__module__, self.__class__.__name__)) + + def signature(self, value): + return base64_hmac(self.salt + 'signer', value, self.key) + + def sign(self, value): + return '%s%s%s' % (value, self.sep, self.signature(value)) + + def unsign(self, signed_value): + if not self.sep in signed_value: + raise ValueError('No "%s" found in value' % self.sep) + value, sig = signed_value.rsplit(self.sep, 1) + if constant_time_compare(sig, self.signature(value)): + return value + raise ValueError('Signature "%s" does not match' % sig) + +try: + from django.core.signing import Signer +except ImportError: + Signer = LegacySigner + diff --git a/directupload/models.py b/directupload/models.py new file mode 100644 index 0000000..37528e3 --- /dev/null +++ b/directupload/models.py @@ -0,0 +1,11 @@ +from django.db import models + +from widgets import UploadifyClearableFileInput + +def patch_admin(): + from django.contrib.admin.options import FORMFIELD_FOR_DBFIELD_DEFAULTS + FORMFIELD_FOR_DBFIELD_DEFAULTS[models.ImageField] = {'widget': UploadifyClearableFileInput} + FORMFIELD_FOR_DBFIELD_DEFAULTS[models.FileField] = {'widget': UploadifyClearableFileInput} + +patch_admin() + diff --git a/directupload/static/uploadify/jquery.uploadify.js b/directupload/static/uploadify/jquery.uploadify.js new file mode 100644 index 0000000..f4d790f --- /dev/null +++ b/directupload/static/uploadify/jquery.uploadify.js @@ -0,0 +1,677 @@ +/* +SWFUpload: http://www.swfupload.org, http://swfupload.googlecode.com + +mmSWFUpload 1.0: Flash upload dialog - http://profandesign.se/swfupload/, http://www.vinterwebb.se/ + +SWFUpload is (c) 2006-2007 Lars Huring, Olov Nilzén and Mammon Media and is released under the MIT License: +http://www.opensource.org/licenses/mit-license.php + +SWFUpload 2 is (c) 2007-2008 Jake Roberts and is released under the MIT License: +http://www.opensource.org/licenses/mit-license.php +*/ + +var SWFUpload;if(SWFUpload==undefined){SWFUpload=function(a){this.initSWFUpload(a)}}SWFUpload.prototype.initSWFUpload=function(b){try{this.customSettings={};this.settings=b;this.eventQueue=[];this.movieName="SWFUpload_"+SWFUpload.movieCount++;this.movieElement=null;SWFUpload.instances[this.movieName]=this;this.initSettings();this.loadFlash();this.displayDebugInfo()}catch(a){delete SWFUpload.instances[this.movieName];throw a}};SWFUpload.instances={};SWFUpload.movieCount=0;SWFUpload.version="2.2.0 2009-03-25";SWFUpload.QUEUE_ERROR={QUEUE_LIMIT_EXCEEDED:-100,FILE_EXCEEDS_SIZE_LIMIT:-110,ZERO_BYTE_FILE:-120,INVALID_FILETYPE:-130};SWFUpload.UPLOAD_ERROR={HTTP_ERROR:-200,MISSING_UPLOAD_URL:-210,IO_ERROR:-220,SECURITY_ERROR:-230,UPLOAD_LIMIT_EXCEEDED:-240,UPLOAD_FAILED:-250,SPECIFIED_FILE_ID_NOT_FOUND:-260,FILE_VALIDATION_FAILED:-270,FILE_CANCELLED:-280,UPLOAD_STOPPED:-290};SWFUpload.FILE_STATUS={QUEUED:-1,IN_PROGRESS:-2,ERROR:-3,COMPLETE:-4,CANCELLED:-5};SWFUpload.BUTTON_ACTION={SELECT_FILE:-100,SELECT_FILES:-110,START_UPLOAD:-120};SWFUpload.CURSOR={ARROW:-1,HAND:-2};SWFUpload.WINDOW_MODE={WINDOW:"window",TRANSPARENT:"transparent",OPAQUE:"opaque"};SWFUpload.completeURL=function(a){if(typeof(a)!=="string"||a.match(/^https?:\/\//i)||a.match(/^\//)){return a}var c=window.location.protocol+"//"+window.location.hostname+(window.location.port?":"+window.location.port:"");var b=window.location.pathname.lastIndexOf("/");if(b<=0){path="/"}else{path=window.location.pathname.substr(0,b)+"/"}return path+a};SWFUpload.prototype.initSettings=function(){this.ensureDefault=function(b,a){this.settings[b]=(this.settings[b]==undefined)?a:this.settings[b]};this.ensureDefault("upload_url","");this.ensureDefault("preserve_relative_urls",false);this.ensureDefault("file_post_name","Filedata");this.ensureDefault("post_params",{});this.ensureDefault("use_query_string",false);this.ensureDefault("requeue_on_error",false);this.ensureDefault("http_success",[]);this.ensureDefault("assume_success_timeout",0);this.ensureDefault("file_types","*.*");this.ensureDefault("file_types_description","All Files");this.ensureDefault("file_size_limit",0);this.ensureDefault("file_upload_limit",0);this.ensureDefault("file_queue_limit",0);this.ensureDefault("flash_url","swfupload.swf");this.ensureDefault("prevent_swf_caching",true);this.ensureDefault("button_image_url","");this.ensureDefault("button_width",1);this.ensureDefault("button_height",1);this.ensureDefault("button_text","");this.ensureDefault("button_text_style","color: #000000; font-size: 16pt;");this.ensureDefault("button_text_top_padding",0);this.ensureDefault("button_text_left_padding",0);this.ensureDefault("button_action",SWFUpload.BUTTON_ACTION.SELECT_FILES);this.ensureDefault("button_disabled",false);this.ensureDefault("button_placeholder_id","");this.ensureDefault("button_placeholder",null);this.ensureDefault("button_cursor",SWFUpload.CURSOR.ARROW);this.ensureDefault("button_window_mode",SWFUpload.WINDOW_MODE.WINDOW);this.ensureDefault("debug",false);this.settings.debug_enabled=this.settings.debug;this.settings.return_upload_start_handler=this.returnUploadStart;this.ensureDefault("swfupload_loaded_handler",null);this.ensureDefault("file_dialog_start_handler",null);this.ensureDefault("file_queued_handler",null);this.ensureDefault("file_queue_error_handler",null);this.ensureDefault("file_dialog_complete_handler",null);this.ensureDefault("upload_start_handler",null);this.ensureDefault("upload_progress_handler",null);this.ensureDefault("upload_error_handler",null);this.ensureDefault("upload_success_handler",null);this.ensureDefault("upload_complete_handler",null);this.ensureDefault("debug_handler",this.debugMessage);this.ensureDefault("custom_settings",{});this.customSettings=this.settings.custom_settings;if(!!this.settings.prevent_swf_caching){this.settings.flash_url=this.settings.flash_url+(this.settings.flash_url.indexOf("?")<0?"?":"&")+"preventswfcaching="+new Date().getTime()}if(!this.settings.preserve_relative_urls){this.settings.upload_url=SWFUpload.completeURL(this.settings.upload_url);this.settings.button_image_url=SWFUpload.completeURL(this.settings.button_image_url)}delete this.ensureDefault};SWFUpload.prototype.loadFlash=function(){var a,b;if(document.getElementById(this.movieName)!==null){throw"ID "+this.movieName+" is already in use. The Flash Object could not be added"}a=document.getElementById(this.settings.button_placeholder_id)||this.settings.button_placeholder;if(a==undefined){throw"Could not find the placeholder element: "+this.settings.button_placeholder_id}b=document.createElement("div");b.innerHTML=this.getFlashHTML();a.parentNode.replaceChild(b.firstChild,a);if(window[this.movieName]==undefined){window[this.movieName]=this.getMovieElement()}};SWFUpload.prototype.getFlashHTML=function(){return['','','','','','','',""].join("")};SWFUpload.prototype.getFlashVars=function(){var b=this.buildParamString();var a=this.settings.http_success.join(",");return["movieName=",encodeURIComponent(this.movieName),"&uploadURL=",encodeURIComponent(this.settings.upload_url),"&useQueryString=",encodeURIComponent(this.settings.use_query_string),"&requeueOnError=",encodeURIComponent(this.settings.requeue_on_error),"&httpSuccess=",encodeURIComponent(a),"&assumeSuccessTimeout=",encodeURIComponent(this.settings.assume_success_timeout),"&params=",encodeURIComponent(b),"&filePostName=",encodeURIComponent(this.settings.file_post_name),"&fileTypes=",encodeURIComponent(this.settings.file_types),"&fileTypesDescription=",encodeURIComponent(this.settings.file_types_description),"&fileSizeLimit=",encodeURIComponent(this.settings.file_size_limit),"&fileUploadLimit=",encodeURIComponent(this.settings.file_upload_limit),"&fileQueueLimit=",encodeURIComponent(this.settings.file_queue_limit),"&debugEnabled=",encodeURIComponent(this.settings.debug_enabled),"&buttonImageURL=",encodeURIComponent(this.settings.button_image_url),"&buttonWidth=",encodeURIComponent(this.settings.button_width),"&buttonHeight=",encodeURIComponent(this.settings.button_height),"&buttonText=",encodeURIComponent(this.settings.button_text),"&buttonTextTopPadding=",encodeURIComponent(this.settings.button_text_top_padding),"&buttonTextLeftPadding=",encodeURIComponent(this.settings.button_text_left_padding),"&buttonTextStyle=",encodeURIComponent(this.settings.button_text_style),"&buttonAction=",encodeURIComponent(this.settings.button_action),"&buttonDisabled=",encodeURIComponent(this.settings.button_disabled),"&buttonCursor=",encodeURIComponent(this.settings.button_cursor)].join("")};SWFUpload.prototype.getMovieElement=function(){if(this.movieElement==undefined){this.movieElement=document.getElementById(this.movieName)}if(this.movieElement===null){throw"Could not find Flash element"}return this.movieElement};SWFUpload.prototype.buildParamString=function(){var c=this.settings.post_params;var b=[];if(typeof(c)==="object"){for(var a in c){if(c.hasOwnProperty(a)){b.push(encodeURIComponent(a.toString())+"="+encodeURIComponent(c[a].toString()))}}}return b.join("&")};SWFUpload.prototype.destroy=function(){try{this.cancelUpload(null,false);var a=null;a=this.getMovieElement();if(a&&typeof(a.CallFunction)==="unknown"){for(var c in a){try{if(typeof(a[c])==="function"){a[c]=null}}catch(e){}}try{a.parentNode.removeChild(a)}catch(b){}}window[this.movieName]=null;SWFUpload.instances[this.movieName]=null;delete SWFUpload.instances[this.movieName];this.movieElement=null;this.settings=null;this.customSettings=null;this.eventQueue=null;this.movieName=null;return true}catch(d){return false}};SWFUpload.prototype.displayDebugInfo=function(){this.debug(["---SWFUpload Instance Info---\n","Version: ",SWFUpload.version,"\n","Movie Name: ",this.movieName,"\n","Settings:\n","\t","upload_url: ",this.settings.upload_url,"\n","\t","flash_url: ",this.settings.flash_url,"\n","\t","use_query_string: ",this.settings.use_query_string.toString(),"\n","\t","requeue_on_error: ",this.settings.requeue_on_error.toString(),"\n","\t","http_success: ",this.settings.http_success.join(", "),"\n","\t","assume_success_timeout: ",this.settings.assume_success_timeout,"\n","\t","file_post_name: ",this.settings.file_post_name,"\n","\t","post_params: ",this.settings.post_params.toString(),"\n","\t","file_types: ",this.settings.file_types,"\n","\t","file_types_description: ",this.settings.file_types_description,"\n","\t","file_size_limit: ",this.settings.file_size_limit,"\n","\t","file_upload_limit: ",this.settings.file_upload_limit,"\n","\t","file_queue_limit: ",this.settings.file_queue_limit,"\n","\t","debug: ",this.settings.debug.toString(),"\n","\t","prevent_swf_caching: ",this.settings.prevent_swf_caching.toString(),"\n","\t","button_placeholder_id: ",this.settings.button_placeholder_id.toString(),"\n","\t","button_placeholder: ",(this.settings.button_placeholder?"Set":"Not Set"),"\n","\t","button_image_url: ",this.settings.button_image_url.toString(),"\n","\t","button_width: ",this.settings.button_width.toString(),"\n","\t","button_height: ",this.settings.button_height.toString(),"\n","\t","button_text: ",this.settings.button_text.toString(),"\n","\t","button_text_style: ",this.settings.button_text_style.toString(),"\n","\t","button_text_top_padding: ",this.settings.button_text_top_padding.toString(),"\n","\t","button_text_left_padding: ",this.settings.button_text_left_padding.toString(),"\n","\t","button_action: ",this.settings.button_action.toString(),"\n","\t","button_disabled: ",this.settings.button_disabled.toString(),"\n","\t","custom_settings: ",this.settings.custom_settings.toString(),"\n","Event Handlers:\n","\t","swfupload_loaded_handler assigned: ",(typeof this.settings.swfupload_loaded_handler==="function").toString(),"\n","\t","file_dialog_start_handler assigned: ",(typeof this.settings.file_dialog_start_handler==="function").toString(),"\n","\t","file_queued_handler assigned: ",(typeof this.settings.file_queued_handler==="function").toString(),"\n","\t","file_queue_error_handler assigned: ",(typeof this.settings.file_queue_error_handler==="function").toString(),"\n","\t","upload_start_handler assigned: ",(typeof this.settings.upload_start_handler==="function").toString(),"\n","\t","upload_progress_handler assigned: ",(typeof this.settings.upload_progress_handler==="function").toString(),"\n","\t","upload_error_handler assigned: ",(typeof this.settings.upload_error_handler==="function").toString(),"\n","\t","upload_success_handler assigned: ",(typeof this.settings.upload_success_handler==="function").toString(),"\n","\t","upload_complete_handler assigned: ",(typeof this.settings.upload_complete_handler==="function").toString(),"\n","\t","debug_handler assigned: ",(typeof this.settings.debug_handler==="function").toString(),"\n"].join(""))};SWFUpload.prototype.addSetting=function(b,c,a){if(c==undefined){return(this.settings[b]=a)}else{return(this.settings[b]=c)}};SWFUpload.prototype.getSetting=function(a){if(this.settings[a]!=undefined){return this.settings[a]}return""};SWFUpload.prototype.callFlash=function(functionName,argumentArray){argumentArray=argumentArray||[];var movieElement=this.getMovieElement();var returnValue,returnString;try{returnString=movieElement.CallFunction(''+__flash__argumentsToXML(argumentArray,0)+"");returnValue=eval(returnString)}catch(ex){throw"Call to "+functionName+" failed"}if(returnValue!=undefined&&typeof returnValue.post==="object"){returnValue=this.unescapeFilePostParams(returnValue)}return returnValue};SWFUpload.prototype.selectFile=function(){this.callFlash("SelectFile")};SWFUpload.prototype.selectFiles=function(){this.callFlash("SelectFiles")};SWFUpload.prototype.startUpload=function(a){this.callFlash("StartUpload",[a])};SWFUpload.prototype.cancelUpload=function(a,b){if(b!==false){b=true}this.callFlash("CancelUpload",[a,b])};SWFUpload.prototype.stopUpload=function(){this.callFlash("StopUpload")};SWFUpload.prototype.getStats=function(){return this.callFlash("GetStats")};SWFUpload.prototype.setStats=function(a){this.callFlash("SetStats",[a])};SWFUpload.prototype.getFile=function(a){if(typeof(a)==="number"){return this.callFlash("GetFileByIndex",[a])}else{return this.callFlash("GetFile",[a])}};SWFUpload.prototype.addFileParam=function(a,b,c){return this.callFlash("AddFileParam",[a,b,c])};SWFUpload.prototype.removeFileParam=function(a,b){this.callFlash("RemoveFileParam",[a,b])};SWFUpload.prototype.setUploadURL=function(a){this.settings.upload_url=a.toString();this.callFlash("SetUploadURL",[a])};SWFUpload.prototype.setPostParams=function(a){this.settings.post_params=a;this.callFlash("SetPostParams",[a])};SWFUpload.prototype.addPostParam=function(a,b){this.settings.post_params[a]=b;this.callFlash("SetPostParams",[this.settings.post_params])};SWFUpload.prototype.removePostParam=function(a){delete this.settings.post_params[a];this.callFlash("SetPostParams",[this.settings.post_params])};SWFUpload.prototype.setFileTypes=function(a,b){this.settings.file_types=a;this.settings.file_types_description=b;this.callFlash("SetFileTypes",[a,b])};SWFUpload.prototype.setFileSizeLimit=function(a){this.settings.file_size_limit=a;this.callFlash("SetFileSizeLimit",[a])};SWFUpload.prototype.setFileUploadLimit=function(a){this.settings.file_upload_limit=a;this.callFlash("SetFileUploadLimit",[a])};SWFUpload.prototype.setFileQueueLimit=function(a){this.settings.file_queue_limit=a;this.callFlash("SetFileQueueLimit",[a])};SWFUpload.prototype.setFilePostName=function(a){this.settings.file_post_name=a;this.callFlash("SetFilePostName",[a])};SWFUpload.prototype.setUseQueryString=function(a){this.settings.use_query_string=a;this.callFlash("SetUseQueryString",[a])};SWFUpload.prototype.setRequeueOnError=function(a){this.settings.requeue_on_error=a;this.callFlash("SetRequeueOnError",[a])};SWFUpload.prototype.setHTTPSuccess=function(a){if(typeof a==="string"){a=a.replace(" ","").split(",")}this.settings.http_success=a;this.callFlash("SetHTTPSuccess",[a])};SWFUpload.prototype.setAssumeSuccessTimeout=function(a){this.settings.assume_success_timeout=a;this.callFlash("SetAssumeSuccessTimeout",[a])};SWFUpload.prototype.setDebugEnabled=function(a){this.settings.debug_enabled=a;this.callFlash("SetDebugEnabled",[a])};SWFUpload.prototype.setButtonImageURL=function(a){if(a==undefined){a=""}this.settings.button_image_url=a;this.callFlash("SetButtonImageURL",[a])};SWFUpload.prototype.setButtonDimensions=function(c,a){this.settings.button_width=c;this.settings.button_height=a;var b=this.getMovieElement();if(b!=undefined){b.style.width=c+"px";b.style.height=a+"px"}this.callFlash("SetButtonDimensions",[c,a])};SWFUpload.prototype.setButtonText=function(a){this.settings.button_text=a;this.callFlash("SetButtonText",[a])};SWFUpload.prototype.setButtonTextPadding=function(b,a){this.settings.button_text_top_padding=a;this.settings.button_text_left_padding=b;this.callFlash("SetButtonTextPadding",[b,a])};SWFUpload.prototype.setButtonTextStyle=function(a){this.settings.button_text_style=a;this.callFlash("SetButtonTextStyle",[a])};SWFUpload.prototype.setButtonDisabled=function(a){this.settings.button_disabled=a;this.callFlash("SetButtonDisabled",[a])};SWFUpload.prototype.setButtonAction=function(a){this.settings.button_action=a;this.callFlash("SetButtonAction",[a])};SWFUpload.prototype.setButtonCursor=function(a){this.settings.button_cursor=a;this.callFlash("SetButtonCursor",[a])};SWFUpload.prototype.queueEvent=function(b,c){if(c==undefined){c=[]}else{if(!(c instanceof Array)){c=[c]}}var a=this;if(typeof this.settings[b]==="function"){this.eventQueue.push(function(){this.settings[b].apply(this,c)});setTimeout(function(){a.executeNextEvent()},0)}else{if(this.settings[b]!==null){throw"Event handler "+b+" is unknown or is not a function"}}};SWFUpload.prototype.executeNextEvent=function(){var a=this.eventQueue?this.eventQueue.shift():null;if(typeof(a)==="function"){a.apply(this)}};SWFUpload.prototype.unescapeFilePostParams=function(c){var e=/[$]([0-9a-f]{4})/i;var f={};var d;if(c!=undefined){for(var a in c.post){if(c.post.hasOwnProperty(a)){d=a;var b;while((b=e.exec(d))!==null){d=d.replace(b[0],String.fromCharCode(parseInt("0x"+b[1],16)))}f[d]=c.post[a]}}c.post=f}return c};SWFUpload.prototype.testExternalInterface=function(){try{return this.callFlash("TestExternalInterface")}catch(a){return false}};SWFUpload.prototype.flashReady=function(){var a=this.getMovieElement();if(!a){this.debug("Flash called back ready but the flash movie can't be found.");return}this.cleanUp(a);this.queueEvent("swfupload_loaded_handler")};SWFUpload.prototype.cleanUp=function(a){try{if(this.movieElement&&typeof(a.CallFunction)==="unknown"){this.debug("Removing Flash functions hooks (this should only run in IE and should prevent memory leaks)");for(var c in a){try{if(typeof(a[c])==="function"){a[c]=null}}catch(b){}}}}catch(d){}window.__flash__removeCallback=function(e,f){try{if(e){e[f]=null}}catch(g){}}};SWFUpload.prototype.fileDialogStart=function(){this.queueEvent("file_dialog_start_handler")};SWFUpload.prototype.fileQueued=function(a){a=this.unescapeFilePostParams(a);this.queueEvent("file_queued_handler",a)};SWFUpload.prototype.fileQueueError=function(a,c,b){a=this.unescapeFilePostParams(a);this.queueEvent("file_queue_error_handler",[a,c,b])};SWFUpload.prototype.fileDialogComplete=function(b,c,a){this.queueEvent("file_dialog_complete_handler",[b,c,a])};SWFUpload.prototype.uploadStart=function(a){a=this.unescapeFilePostParams(a);this.queueEvent("return_upload_start_handler",a)};SWFUpload.prototype.returnUploadStart=function(a){var b;if(typeof this.settings.upload_start_handler==="function"){a=this.unescapeFilePostParams(a);b=this.settings.upload_start_handler.call(this,a)}else{if(this.settings.upload_start_handler!=undefined){throw"upload_start_handler must be a function"}}if(b===undefined){b=true}b=!!b;this.callFlash("ReturnUploadStart",[b])};SWFUpload.prototype.uploadProgress=function(a,c,b){a=this.unescapeFilePostParams(a);this.queueEvent("upload_progress_handler",[a,c,b])};SWFUpload.prototype.uploadError=function(a,c,b){a=this.unescapeFilePostParams(a);this.queueEvent("upload_error_handler",[a,c,b])};SWFUpload.prototype.uploadSuccess=function(b,a,c){b=this.unescapeFilePostParams(b);this.queueEvent("upload_success_handler",[b,a,c])};SWFUpload.prototype.uploadComplete=function(a){a=this.unescapeFilePostParams(a);this.queueEvent("upload_complete_handler",a)};SWFUpload.prototype.debug=function(a){this.queueEvent("debug_handler",a)};SWFUpload.prototype.debugMessage=function(c){if(this.settings.debug){var a,d=[];if(typeof c==="object"&&typeof c.name==="string"&&typeof c.message==="string"){for(var b in c){if(c.hasOwnProperty(b)){d.push(b+": "+c[b])}}a=d.join("\n")||"";d=a.split("\n");a="EXCEPTION: "+d.join("\nEXCEPTION: ");SWFUpload.Console.writeLine(a)}else{SWFUpload.Console.writeLine(c)}}};SWFUpload.Console={};SWFUpload.Console.writeLine=function(d){var b,a;try{b=document.getElementById("SWFUpload_Console");if(!b){a=document.createElement("form");document.getElementsByTagName("body")[0].appendChild(a);b=document.createElement("textarea");b.id="SWFUpload_Console";b.style.fontFamily="monospace";b.setAttribute("wrap","off");b.wrap="off";b.style.overflow="auto";b.style.width="700px";b.style.height="350px";b.style.margin="5px";a.appendChild(b)}b.value+=d+"\n";b.scrollTop=b.scrollHeight-b.clientHeight}catch(c){alert("Exception: "+c.name+" Message: "+c.message)}}; + +/* +Uploadify v3.0.0 +Copyright (c) 2010 Ronnie Garcia + +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. +*/ + +if(jQuery)( + function(jQuery){ + jQuery.extend(jQuery.fn,{ + uploadify:function(options,swfUploadOptions) { + jQuery(this).each(function() { + var clone = jQuery(this).clone(); + var settings = jQuery.extend({ + // Required Settings + id : jQuery(this).attr('id'), + swf : 'uploadify.swf', + uploader : 'uploadify.php', + + // Options + auto : false, + buttonClass : '', + buttonCursor : 'hand', + buttonImage : false, + buttonText : 'SELECT FILES', + cancelImage : 'uploadify-cancel.png', + checkExisting : 'uploadify-check-existing.php', + debug : false, + fileObjName : 'Filedata', + fileSizeLimit : 0, + fileTypeDesc : 'All Files (*.*)', + fileTypeExts : '*.*', + height : 30, + method : 'post', + multi : false, + queueID : false, + queueSizeLimit : 999, + removeCompleted : true, + removeTimeout : 3, + requeueErrors : false, + postData : {}, + preventCaching : true, + progressData : 'percentage', + // simUploadLimit : 1, // Not possible with swfUpload + successTimeout : 30, + transparent : true, + uploadLimit : 999, + uploaderType : 'html5', // the other option is 'flash' + width : 120, + + // Events + skipDefault : [], + onClearQueue : function() {}, + onDialogOpen : function() {}, + onDialogClose : function() {}, + onInit : function() {}, + onQueueComplete : function() {}, + onSelectError : function() {}, + onSelect : function() {}, + onSWFReady : function() {}, + onUploadCancel : function() {}, + onUploadComplete : function() {}, + onUploadError : function() {}, + onUploadProgress : function() {}, + onUploadStart : function() {} + }, options); + + var swfUploadSettings = { + assume_success_timeout : settings.successTimeout, + button_placeholder_id : settings.id, + button_image_url : settings.buttonImage, + button_width : settings.width, + button_height : settings.height, + button_text : null, + button_text_style : null, + button_text_top_padding : 0, + button_text_left_padding : 0, + button_action : (settings.multi ? SWFUpload.BUTTON_ACTION.SELECT_FILES : SWFUpload.BUTTON_ACTION.SELECT_FILE), + button_disabled : false, + button_cursor : (settings.buttonCursor == 'arrow' ? SWFUpload.CURSOR.ARROW : SWFUpload.CURSOR.HAND), + button_window_mode : (settings.transparent && !settings.buttonImage ? SWFUpload.WINDOW_MODE.TRANSPARENT : SWFUpload.WINDOW_MODE.OPAQUE), + debug : settings.debug, + requeue_on_error : settings.requeueErrors, + file_post_name : settings.fileObjName, + file_size_limit : settings.fileSizeLimit, + file_types : settings.fileTypeExts, + file_types_description : settings.fileTypeDesc, + file_queue_limit : settings.queueSizeLimit, + file_upload_limit : settings.uploadLimit, + flash_url : settings.swf, + prevent_swf_caching : settings.preventCaching, + post_params : settings.postData, + upload_url : settings.uploader, + use_query_string : (settings.method == 'get'), + + // Event Handlers + file_dialog_complete_handler : onDialogClose, + file_dialog_start_handler : onDialogOpen, + file_queued_handler : onSelect, + file_queue_error_handler : onSelectError, + flash_ready_handler : settings.onSWFReady, + upload_complete_handler : onUploadComplete, + upload_error_handler : onUploadError, + upload_progress_handler : onUploadProgress, + upload_start_handler : onUploadStart, + upload_success_handler : onUploadSuccess + } + if (swfUploadOptions) { + swfUploadSettings = jQuery.extend(swfUploadSettings,swfUploadOptions); + } + swfUploadSettings = jQuery.extend(swfUploadSettings,settings); + + // Create the swfUpload instance + window['uploadify_' + settings.id] = new SWFUpload(swfUploadSettings); + var swfuploadify = window['uploadify_' + settings.id]; + swfuploadify.original = clone; + + // Wrap the uploadify instance + var wrapper = jQuery('
',{ + id : settings.id, + 'class' : 'uploadify', + css : { + 'height' : settings.height + 'px', + 'position' : 'relative', + 'width' : settings.width + 'px' + } + }); + jQuery('#' + swfuploadify.movieName).wrap(wrapper); + + // Create the file queue + if (!settings.queueID) { + var queue = jQuery('
', { + id : settings.id + '_queue', + 'class' : 'uploadifyQueue' + }); + jQuery('#' + settings.id).after(queue); + swfuploadify.settings.queueID = settings.queueID = settings.id + '_queue'; + } + + // Create some queue related objects and variables + swfuploadify.queue = { + files : {}, // The files in the queue + filesSelected : 0, // The number of files selected in the last select operation + filesQueued : 0, // The number of files added to the queue in the last select operation + filesReplaced : 0, // The number of files replaced in the last select operation + filesCancelled : 0, // The number of files that were cancelled instead of replaced + filesErrored : 0, // The number of files that caused error in the last select operation + averageSpeed : 0, // The average speed of the uploads in KB + queueLength : 0, // The number of files in the queue + queueSize : 0, // The size in bytes of the entire queue + uploadSize : 0, // The size in bytes of the upload queue + queueBytesUploaded : 0, // The size in bytes that have been uploaded for the current upload queue + uploadQueue : [], // The files currently to be uploaded + errorMsg : 'Some files were not added to the queue:' + }; + + // Create the button + if (!settings.buttonImage) { + var button = jQuery('
', { + id : settings.id + '_button', + 'class' : 'uploadifyButton ' + settings.buttonClass, + html : '' + settings.buttonText + '' + }); + jQuery('#' + settings.id).append(button); + jQuery('#' + swfuploadify.movieName).css({position: 'absolute', 'z-index': 1}); + } else { + jQuery('#' + swfuploadify.movieName).addClass(settings.buttonClass); + } + + // ----------------------------- + // Begin Event Handler Functions + // ----------------------------- + + // Triggered once when file dialog is closed + function onDialogClose(filesSelected,filesQueued,queueLength) { + var stats = swfuploadify.getStats(); + swfuploadify.queue.filesErrored = filesSelected - filesQueued; + swfuploadify.queue.filesSelected = filesSelected; + swfuploadify.queue.filesQueued = filesQueued - swfuploadify.queue.filesCancelled; + swfuploadify.queue.queueLength = queueLength; + if (jQuery.inArray('onDialogClose',swfuploadify.settings.skipDefault) < 0) { + if (swfuploadify.queue.filesErrored > 0) { + alert(swfuploadify.queue.errorMsg); + } + } + if (swfuploadify.settings.onDialogClose) swfuploadify.settings.onDialogClose(swfuploadify.queue); + if (swfuploadify.settings.auto) jQuery('#' + swfuploadify.settings.id).uploadifyUpload('*'); + } + + function onDialogOpen() { + // Reset some queue info + swfuploadify.queue.errorMsg = 'Some files were not added to the queue:'; + swfuploadify.queue.filesReplaced = 0; + swfuploadify.queue.filesCancelled = 0; + if (swfuploadify.settings.onDialogOpen) swfuploadify.settings.onDialogOpen(); + } + + // Triggered once for each file added to the queue + function onSelect(file) { + if (jQuery.inArray('onSelect',swfuploadify.settings.skipDefault) < 0) { + // Check if a file with the same name exists in the queue + var queuedFile = {}; + for (var n in swfuploadify.queue.files) { + queuedFile = swfuploadify.queue.files[n]; + if (queuedFile.name == file.name) { + var replaceQueueItem = confirm('The file named "' + file.name + '" is already in the queue.\nDo you want to replace the existing item in the queue?'); + if (!replaceQueueItem) { + swfuploadify.cancelUpload(file.id); + swfuploadify.queue.filesCancelled++; + return false; + } else { + jQuery('#' + queuedFile.id).remove(); + swfuploadify.cancelUpload(queuedFile.id); + swfuploadify.queue.filesReplaced++; + } + } + } + + // Get the size of the file + var fileSize = Math.round(file.size / 1024); + var suffix = 'KB'; + if (fileSize > 1000) { + fileSize = Math.round(fileSize / 1000); + suffix = 'MB'; + } + var fileSizeParts = fileSize.toString().split('.'); + fileSize = fileSizeParts[0]; + if (fileSizeParts.length > 1) { + fileSize += '.' + fileSizeParts[1].substr(0,2); + } + fileSize += suffix; + + // Truncate the filename if it's too long + var fileName = file.name; + if (fileName.length > 25) { + fileName = fileName.substr(0,25) + '...'; + } + + // Add the file item to the queue + jQuery('#' + swfuploadify.settings.queueID).append('
\ +
\ + \ +
\ + ' + fileName + ' (' + fileSize + ')\ +
\ +
\ +
\ +
'); + swfuploadify.queue.queueSize += file.size; + } + swfuploadify.queue.files[file.id] = file; + if (swfuploadify.settings.onSelect) swfuploadify.settings.onSelect(file); + } + + // Triggered when a file is not added to the queue + function onSelectError(file,errorCode,errorMsg) { + if (jQuery.inArray('onSelectError',swfuploadify.settings.skipDefault) < 0) { + switch(errorCode) { + case SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED: + if (swfuploadify.settings.queueSizeLimit > errorMsg) { + swfuploadify.queue.errorMsg += '\nThe number of files selected exceeds the remaining upload limit (' + errorMsg + ').'; + } else { + swfuploadify.queue.errorMsg += '\nThe number of files selected exceeds the queue size limit (' + swfuploadify.settings.queueSizeLimit + ').'; + } + break; + case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT: + swfuploadify.queue.errorMsg += '\nThe file "' + file.name + '" exceeds the size limit (' + swfuploadify.settings.fileSizeLimit + ').'; + break; + case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE: + swfuploadify.queue.errorMsg += '\nThe file "' + file.name + '" is empty.'; + break; + case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT: + swfuploadify.queue.errorMsg += '\nThe file "' + file.name + '" is not an accepted file type (' + swfuploadify.settings.fileTypeDesc + ').'; + break; + } + } + if (errorCode != SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED) { + delete swfuploadify.queue.files[file.id]; + } + if (swfuploadify.settings.onSelectError) swfuploadify.settings.onSelectError(file,errorCode,errorMsg); + } + + // Triggered when all the files in the queue have been processed + function onQueueComplete() { + var stats = swfuploadify.getStats(); + if (swfuploadify.settings.onQueueComplete) swfuploadify.settings.onQueueComplete(stats); + } + + // Triggered when a file upload successfully completes + function onUploadComplete(file) { + var stats = swfuploadify.getStats(); + swfuploadify.queue.queueLength = stats.files_queued; + if (swfuploadify.queue.uploadQueue[0] == '*') { + if (swfuploadify.queue.queueLength > 0) { + swfuploadify.startUpload(); + } else { + swfuploadify.queue.uploadQueue = []; + if (swfuploadify.settings.onQueueComplete) swfuploadify.settings.onQueueComplete(stats); + } + } else { + if (swfuploadify.queue.uploadQueue.length > 0) { + swfuploadify.startUpload(swfuploadify.queue.uploadQueue.shift()); + } else { + swfuploadify.queue.uploadQueue = []; + if (swfuploadify.settings.onQueueComplete) setting.onQueueComplete(stats); + } + } + if (jQuery.inArray('onUploadComplete',swfuploadify.settings.skipDefault) < 0) { + if (swfuploadify.settings.removeCompleted) { + switch (file.filestatus) { + case SWFUpload.FILE_STATUS.COMPLETE: + setTimeout(function() { + if (jQuery('#' + file.id)) { + swfuploadify.queue.queueSize -= file.size; + delete swfuploadify.queue.files[file.id] + jQuery('#' + file.id).fadeOut(500,function() { + jQuery(this).remove(); + }); + } + },swfuploadify.settings.removeTimeout * 1000); + break; + case SWFUpload.FILE_STATUS.ERROR: + if (!swfuploadify.settings.requeueErrors) { + setTimeout(function() { + if (jQuery('#' + file.id)) { + swfuploadify.queue.queueSize -= file.size; + delete swfuploadify.queue.files[file.id]; + jQuery('#' + file.id).fadeOut(500,function() { + jQuery(this).remove(); + }); + } + },swfuploadify.settings.removeTimeout * 1000); + } + break; + } + } + } + if (swfuploadify.settings.onUploadComplete) swfuploadify.settings.onUploadComplete(file,swfuploadify.queue); + } + + // Triggered when a file upload returns an error + function onUploadError(file,errorCode,errorMsg) { + var errorString = 'Error'; + if (errorCode != SWFUpload.UPLOAD_ERROR.FILE_CANCELLED && errorCode != SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED) { + jQuery('#' + file.id).addClass('uploadifyError'); + } + jQuery('#' + file.id).find('.uploadifyProgressBar').css('width','1px'); + switch(errorCode) { + case SWFUpload.UPLOAD_ERROR.HTTP_ERROR: + errorString = 'HTTP Error (' + errorMsg + ')'; + break; + case SWFUpload.UPLOAD_ERROR.MISSING_UPLOAD_URL: + errorString = 'Missing Upload URL'; + break; + case SWFUpload.UPLOAD_ERROR.IO_ERROR: + errorString = 'IO Error'; + break; + case SWFUpload.UPLOAD_ERROR.SECURITY_ERROR: + errorString = 'Security Error'; + break; + case SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED: + alert('The upload limit has been reached (' + errorMsg + ').'); + errorString = 'Exceeds Upload Limit'; + break; + case SWFUpload.UPLOAD_ERROR.UPLOAD_FAILED: + errorString = 'Failed'; + break; + case SWFUpload.UPLOAD_ERROR.SPECIFIED_FILE_ID_NOT_FOUND: + break; + case SWFUpload.UPLOAD_ERROR.FILE_VALIDATION_FAILED: + errorString = 'Validation Error'; + break; + case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED: + errorString = 'Cancelled'; + swfuploadify.queue.queueSize -= file.size; + if (file.status == SWFUpload.FILE_STATUS.IN_PROGRESS || jQuery.inArray(file.id,swfuploadify.queue.uploadQueue) >= 0) { + swfuploadify.queue.uploadSize -= file.size; + } + delete swfuploadify.queue.files[file.id]; + break; + case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED: + errorString = 'Stopped'; + break; + } + if (errorCode != SWFUpload.UPLOAD_ERROR.SPECIFIED_FILE_ID_NOT_FOUND && file.status != SWFUpload.FILE_STATUS.COMPLETE) { + jQuery('#' + file.id).find('.data').html(' - ' + errorString); + } + if (swfuploadify.settings.onUploadError) swfuploadify.settings.onUploadError(file,errorCode,errorMsg,errorString,swfuploadify.queue); + } + + // Triggered periodically during a file upload + function onUploadProgress(file,fileBytesLoaded,fileTotalBytes) { + var timer = new Date(); + var newTime = timer.getTime(); + var lapsedTime = newTime - swfuploadify.timer; + swfuploadify.timer = newTime; + var lapsedBytes = fileBytesLoaded - swfuploadify.bytesLoaded; + swfuploadify.bytesLoaded = fileBytesLoaded; + var queueBytesLoaded = swfuploadify.queue.queueBytesUploaded + fileBytesLoaded; + var percentage = Math.round(fileBytesLoaded / fileTotalBytes * 100); + + // Calculate the average speed + var mbs = 0; + var kbs = (lapsedBytes / 1024) / (lapsedTime / 1000); + kbs = Math.floor(kbs * 10) / 10; + if (swfuploadify.queue.averageSpeed > 0) { + swfuploadify.queue.averageSpeed = (swfuploadify.queue.averageSpeed + kbs) / 2; + } else { + swfuploadify.queue.averageSpeed = kbs; + } + if (kbs > 1000) { + mbs = (kbs * .001); + swfuploadify.queue.averageSpeed = mbs; + } + var suffix = 'KB/s'; + if (mbs > 0) { + suffix = 'MB/s'; + } + + if (jQuery.inArray('onUploadProgress',swfuploadify.settings.skipDefault) < 0) { + if (swfuploadify.settings.progressData == 'percentage') { + jQuery('#' + file.id).find('.data').html(' - ' + percentage + '%'); + } else if (swfuploadify.settings.progressData == 'speed') { + jQuery('#' + file.id).find('.data').html(' - ' + percentage + suffix); + } + jQuery('#' + file.id).find('.uploadifyProgressBar').css('width',percentage + '%'); + } + if (swfuploadify.settings.onUploadProgress) swfuploadify.settings.onUploadProgress(file,fileBytesLoaded,fileTotalBytes,queueBytesLoaded,swfuploadify.queue.uploadSize); + } + + // Triggered right before a file is uploaded + function onUploadStart(file) { + var timer = new Date(); + swfuploadify.timer = timer.getTime(); + swfuploadify.bytesLoaded = 0; + if (swfuploadify.queue.uploadQueue.length == 0) { + swfuploadify.queue.uploadSize = file.size; + } + if (swfuploadify.settings.checkExisting !== false) { + jQuery.ajax({ + type : 'POST', + async : false, + url : swfuploadify.settings.checkExisting, + data : {filename: file.name}, + success : function(data) { + if (data == 1) { + var overwrite = confirm('A file with the name "' + file.name + '" already exists on the server.\nWould you like to replace the existing file?'); + if (!overwrite) { + swfuploadify.cancelUpload(file.id); + jQuery('#' + file.id).remove(); + if (swfuploadify.queue.uploadQueue.length > 0 && swfuploadify.queue.queueLength > 0) { + if (swfuploadify.queue.uploadQueue[0] == '*') { + swfuploadify.startUpload(); + } else { + swfuploadify.startUpload(swfuploadify.queue.uploadQueue.shift()); + } + } + } + } + } + }); + } + if (swfuploadify.settings.onUploadStart) swfuploadify.settings.onUploadStart(file); + } + + // Triggered when a file upload returns a successful code + function onUploadSuccess(file,data,response) { + swfuploadify.queue.queueBytesUploaded += file.size; + jQuery('#' + file.id).find('.data').html(' - Complete'); + if (swfuploadify.settings.onUploadSuccess) swfuploadify.settings.onUploadSuccess(file,data,response); + } + + // --------------------------- + // End Event Handler Functions + // --------------------------- + }); + }, + + // Cancel a file upload and remove it from the queue + uploadifyCancel:function(fileID) { + var id = jQuery(this).selector.replace('#',''); + var swfuploadify = window['uploadify_' + id]; + var delay = -1; + if (arguments[0]) { + if (arguments[0] == '*') { + jQuery('#' + swfuploadify.settings.queueID).find('.uploadifyQueueItem').each(function() { + delay++; + swfuploadify.cancelUpload(jQuery(this).attr('id')); + jQuery(this).delay(100 * delay).fadeOut(500,function() { + jQuery(this).remove(); + + }); + }); + swfuploadify.queue.queueSize = 0; + } else { + for (var n = 0; n < arguments.length; n++) { + swfuploadify.cancelUpload(arguments[n]); + jQuery('#' + arguments[n]).delay(100 * n).fadeOut(500,function() { + jQuery(this).remove(); + }); + } + } + } else { + jQuery('#' + swfuploadify.settings.queueID).find('.uploadifyQueueItem').get(0).fadeOut(500,function() { + jQuery(this).remove(); + swfuploadify.cancelUpload(jQuery(this).attr('id')); + }); + } + }, + + // Get rid of the instance of Uploadify + uploadifyDestroy:function() { + var id = jQuery(this).selector.replace('#',''); + var swfuploadify = window['uploadify_' + id]; + swfuploadify.destroy(); + jQuery('#' + id + '_queue').remove(); + jQuery('#' + id).replaceWith(swfuploadify.original); + delete window['uploadify_' + id]; + }, + + // Disable the select button + uploadifyDisable:function(isDisabled) { + var id = jQuery(this).selector.replace('#',''); + var swfuploadify = window['uploadify_' + id]; + swfuploadify.setButtonDisabled(isDisabled); + }, + + // Update or retrieve a setting + uploadifySettings:function(name,value,resetObjects) { + var id = jQuery(this).selector.replace('#',''); + var swfuploadify = window['uploadify_' + id]; + if (typeof(arguments[0]) == 'object') { + for (var n in value) { + setData(n,value[n]); + } + } + if (arguments.length == 1) { + return swfuploadify.settings[name]; + } else { + setData(name,value,resetObjects); + } + + function setData(settingName,settingValue,resetObjects) { + switch (settingName) { + case 'uploader': + swfuploadify.setUploadURL(settingValue); + break; + case 'postData': + if (!resetObjects) { + value = jQuery.extend(swfuploadify.settings.postData,settingValue); + } + swfuploadify.setPostParams(settingValue); + break; + case 'method': + if (settingValue == 'get') { + swfuploadify.setUseQueryString(true); + } else { + swfuploadify.setUseQueryString(false); + } + break; + case 'fileObjName': + swfuploadify.setFilePostName(settingValue); + break; + case 'fileTypeExts': + swfuploadify.setFileTypes(settingValue,swfuploadify.settings.fileTypeDesc); + break; + case 'fileTypeDesc': + swfuploadify.setFileTypes(swfuploadify.settings.fileTypeExts,settingValue); + break; + case 'fileSizeLimit': + swfuploadify.setFileSizeLimit(settingValue); + break; + case 'uploadLimit': + swfuploadify.setFileUploadLimit(settingValue); + break; + case 'queueSizeLimit': + swfuploadify.setFileQueueLimit(settingValue); + break; + case 'buttonImage': + jQuery('#' + swfuploadify.settings.id + '_button').remove(); + swfuploadify.setButtonImageURL(settingValue); + break; + case 'buttonCursor': + if (settingValue == 'arrow') { + swfuploadify.setButtonCursor(SWFUpload.CURSOR.ARROW); + } else { + swfuploadify.setButtonCursor(SWFUpload.CURSOR.HAND); + } + break; + case 'buttonText': + jQuery('#' + swfuploadify.settings.id + '_button').find('.uploadifyButtonText').html(settingValue); + break; + case 'width': + swfuploadify.setButtonDimensions(settingValue,swfuploadify.settings.height); + break; + case 'height': + swfuploadify.setButtonDimensions(swfuploadify.settings.width,settingValue); + break; + case 'multi': + if (settingValue) { + swfuploadify.setButtonAction(SWFUpload.BUTTON_ACTION.SELECT_FILES); + } else { + swfuploadify.setButtonAction(SWFUpload.BUTTON_ACTION.SELECT_FILE); + } + break; + } + swfuploadify.settings[settingName] = value; + } + }, + + // Stop the current upload and requeue what is in progress + uploadifyStop:function() { + var id = jQuery(this).selector.replace('#',''); + var swfuploadify = window['uploadify_' + id]; + swfuploadify.stopUpload(); + }, + + // Upload the first file, a select number of files, or all the files in the queue + uploadifyUpload:function() { + var id = jQuery(this).selector.replace('#',''); + var swfuploadify = window['uploadify_' + id]; + + // Reset the queue information + swfuploadify.queue.averageSpeed = 0; + swfuploadify.queue.uploadSize = 0; + swfuploadify.queue.bytesUploaded = 0; + swfuploadify.queue.uploadQueue = []; + + if (arguments[0]) { + if (arguments[0] == '*') { + swfuploadify.queue.uploadSize = swfuploadify.queue.queueSize; + swfuploadify.queue.uploadQueue.push('*'); + swfuploadify.startUpload(); + } else { + for (var n = 0; n < arguments.length; n++) { + swfuploadify.queue.uploadSize += swfuploadify.queue.files[arguments[n]].size; + swfuploadify.queue.uploadQueue.push(arguments[n]); + } + swfuploadify.startUpload(swfuploadify.queue.uploadQueue.shift()); + } + } else { + swfuploadify.startUpload(); + } + } + }) + } +)(jQuery); \ No newline at end of file diff --git a/directupload/static/uploadify/jquery.uploadify.min.js b/directupload/static/uploadify/jquery.uploadify.min.js new file mode 100644 index 0000000..568637e --- /dev/null +++ b/directupload/static/uploadify/jquery.uploadify.min.js @@ -0,0 +1,38 @@ +/* +SWFUpload: http://www.swfupload.org, http://swfupload.googlecode.com + +mmSWFUpload 1.0: Flash upload dialog - http://profandesign.se/swfupload/, http://www.vinterwebb.se/ + +SWFUpload is (c) 2006-2007 Lars Huring, Olov Nilzén and Mammon Media and is released under the MIT License: +http://www.opensource.org/licenses/mit-license.php + +SWFUpload 2 is (c) 2007-2008 Jake Roberts and is released under the MIT License: +http://www.opensource.org/licenses/mit-license.php +*/ + +var SWFUpload;if(SWFUpload==undefined){SWFUpload=function(a){this.initSWFUpload(a)}}SWFUpload.prototype.initSWFUpload=function(b){try{this.customSettings={};this.settings=b;this.eventQueue=[];this.movieName="SWFUpload_"+SWFUpload.movieCount++;this.movieElement=null;SWFUpload.instances[this.movieName]=this;this.initSettings();this.loadFlash();this.displayDebugInfo()}catch(a){delete SWFUpload.instances[this.movieName];throw a}};SWFUpload.instances={};SWFUpload.movieCount=0;SWFUpload.version="2.2.0 2009-03-25";SWFUpload.QUEUE_ERROR={QUEUE_LIMIT_EXCEEDED:-100,FILE_EXCEEDS_SIZE_LIMIT:-110,ZERO_BYTE_FILE:-120,INVALID_FILETYPE:-130};SWFUpload.UPLOAD_ERROR={HTTP_ERROR:-200,MISSING_UPLOAD_URL:-210,IO_ERROR:-220,SECURITY_ERROR:-230,UPLOAD_LIMIT_EXCEEDED:-240,UPLOAD_FAILED:-250,SPECIFIED_FILE_ID_NOT_FOUND:-260,FILE_VALIDATION_FAILED:-270,FILE_CANCELLED:-280,UPLOAD_STOPPED:-290};SWFUpload.FILE_STATUS={QUEUED:-1,IN_PROGRESS:-2,ERROR:-3,COMPLETE:-4,CANCELLED:-5};SWFUpload.BUTTON_ACTION={SELECT_FILE:-100,SELECT_FILES:-110,START_UPLOAD:-120};SWFUpload.CURSOR={ARROW:-1,HAND:-2};SWFUpload.WINDOW_MODE={WINDOW:"window",TRANSPARENT:"transparent",OPAQUE:"opaque"};SWFUpload.completeURL=function(a){if(typeof(a)!=="string"||a.match(/^https?:\/\//i)||a.match(/^\//)){return a}var c=window.location.protocol+"//"+window.location.hostname+(window.location.port?":"+window.location.port:"");var b=window.location.pathname.lastIndexOf("/");if(b<=0){path="/"}else{path=window.location.pathname.substr(0,b)+"/"}return path+a};SWFUpload.prototype.initSettings=function(){this.ensureDefault=function(b,a){this.settings[b]=(this.settings[b]==undefined)?a:this.settings[b]};this.ensureDefault("upload_url","");this.ensureDefault("preserve_relative_urls",false);this.ensureDefault("file_post_name","Filedata");this.ensureDefault("post_params",{});this.ensureDefault("use_query_string",false);this.ensureDefault("requeue_on_error",false);this.ensureDefault("http_success",[]);this.ensureDefault("assume_success_timeout",0);this.ensureDefault("file_types","*.*");this.ensureDefault("file_types_description","All Files");this.ensureDefault("file_size_limit",0);this.ensureDefault("file_upload_limit",0);this.ensureDefault("file_queue_limit",0);this.ensureDefault("flash_url","swfupload.swf");this.ensureDefault("prevent_swf_caching",true);this.ensureDefault("button_image_url","");this.ensureDefault("button_width",1);this.ensureDefault("button_height",1);this.ensureDefault("button_text","");this.ensureDefault("button_text_style","color: #000000; font-size: 16pt;");this.ensureDefault("button_text_top_padding",0);this.ensureDefault("button_text_left_padding",0);this.ensureDefault("button_action",SWFUpload.BUTTON_ACTION.SELECT_FILES);this.ensureDefault("button_disabled",false);this.ensureDefault("button_placeholder_id","");this.ensureDefault("button_placeholder",null);this.ensureDefault("button_cursor",SWFUpload.CURSOR.ARROW);this.ensureDefault("button_window_mode",SWFUpload.WINDOW_MODE.WINDOW);this.ensureDefault("debug",false);this.settings.debug_enabled=this.settings.debug;this.settings.return_upload_start_handler=this.returnUploadStart;this.ensureDefault("swfupload_loaded_handler",null);this.ensureDefault("file_dialog_start_handler",null);this.ensureDefault("file_queued_handler",null);this.ensureDefault("file_queue_error_handler",null);this.ensureDefault("file_dialog_complete_handler",null);this.ensureDefault("upload_start_handler",null);this.ensureDefault("upload_progress_handler",null);this.ensureDefault("upload_error_handler",null);this.ensureDefault("upload_success_handler",null);this.ensureDefault("upload_complete_handler",null);this.ensureDefault("debug_handler",this.debugMessage);this.ensureDefault("custom_settings",{});this.customSettings=this.settings.custom_settings;if(!!this.settings.prevent_swf_caching){this.settings.flash_url=this.settings.flash_url+(this.settings.flash_url.indexOf("?")<0?"?":"&")+"preventswfcaching="+new Date().getTime()}if(!this.settings.preserve_relative_urls){this.settings.upload_url=SWFUpload.completeURL(this.settings.upload_url);this.settings.button_image_url=SWFUpload.completeURL(this.settings.button_image_url)}delete this.ensureDefault};SWFUpload.prototype.loadFlash=function(){var a,b;if(document.getElementById(this.movieName)!==null){throw"ID "+this.movieName+" is already in use. The Flash Object could not be added"}a=document.getElementById(this.settings.button_placeholder_id)||this.settings.button_placeholder;if(a==undefined){throw"Could not find the placeholder element: "+this.settings.button_placeholder_id}b=document.createElement("div");b.innerHTML=this.getFlashHTML();a.parentNode.replaceChild(b.firstChild,a);if(window[this.movieName]==undefined){window[this.movieName]=this.getMovieElement()}};SWFUpload.prototype.getFlashHTML=function(){return['','','','','','','',""].join("")};SWFUpload.prototype.getFlashVars=function(){var b=this.buildParamString();var a=this.settings.http_success.join(",");return["movieName=",encodeURIComponent(this.movieName),"&uploadURL=",encodeURIComponent(this.settings.upload_url),"&useQueryString=",encodeURIComponent(this.settings.use_query_string),"&requeueOnError=",encodeURIComponent(this.settings.requeue_on_error),"&httpSuccess=",encodeURIComponent(a),"&assumeSuccessTimeout=",encodeURIComponent(this.settings.assume_success_timeout),"&params=",encodeURIComponent(b),"&filePostName=",encodeURIComponent(this.settings.file_post_name),"&fileTypes=",encodeURIComponent(this.settings.file_types),"&fileTypesDescription=",encodeURIComponent(this.settings.file_types_description),"&fileSizeLimit=",encodeURIComponent(this.settings.file_size_limit),"&fileUploadLimit=",encodeURIComponent(this.settings.file_upload_limit),"&fileQueueLimit=",encodeURIComponent(this.settings.file_queue_limit),"&debugEnabled=",encodeURIComponent(this.settings.debug_enabled),"&buttonImageURL=",encodeURIComponent(this.settings.button_image_url),"&buttonWidth=",encodeURIComponent(this.settings.button_width),"&buttonHeight=",encodeURIComponent(this.settings.button_height),"&buttonText=",encodeURIComponent(this.settings.button_text),"&buttonTextTopPadding=",encodeURIComponent(this.settings.button_text_top_padding),"&buttonTextLeftPadding=",encodeURIComponent(this.settings.button_text_left_padding),"&buttonTextStyle=",encodeURIComponent(this.settings.button_text_style),"&buttonAction=",encodeURIComponent(this.settings.button_action),"&buttonDisabled=",encodeURIComponent(this.settings.button_disabled),"&buttonCursor=",encodeURIComponent(this.settings.button_cursor)].join("")};SWFUpload.prototype.getMovieElement=function(){if(this.movieElement==undefined){this.movieElement=document.getElementById(this.movieName)}if(this.movieElement===null){throw"Could not find Flash element"}return this.movieElement};SWFUpload.prototype.buildParamString=function(){var c=this.settings.post_params;var b=[];if(typeof(c)==="object"){for(var a in c){if(c.hasOwnProperty(a)){b.push(encodeURIComponent(a.toString())+"="+encodeURIComponent(c[a].toString()))}}}return b.join("&")};SWFUpload.prototype.destroy=function(){try{this.cancelUpload(null,false);var a=null;a=this.getMovieElement();if(a&&typeof(a.CallFunction)==="unknown"){for(var c in a){try{if(typeof(a[c])==="function"){a[c]=null}}catch(e){}}try{a.parentNode.removeChild(a)}catch(b){}}window[this.movieName]=null;SWFUpload.instances[this.movieName]=null;delete SWFUpload.instances[this.movieName];this.movieElement=null;this.settings=null;this.customSettings=null;this.eventQueue=null;this.movieName=null;return true}catch(d){return false}};SWFUpload.prototype.displayDebugInfo=function(){this.debug(["---SWFUpload Instance Info---\n","Version: ",SWFUpload.version,"\n","Movie Name: ",this.movieName,"\n","Settings:\n","\t","upload_url: ",this.settings.upload_url,"\n","\t","flash_url: ",this.settings.flash_url,"\n","\t","use_query_string: ",this.settings.use_query_string.toString(),"\n","\t","requeue_on_error: ",this.settings.requeue_on_error.toString(),"\n","\t","http_success: ",this.settings.http_success.join(", "),"\n","\t","assume_success_timeout: ",this.settings.assume_success_timeout,"\n","\t","file_post_name: ",this.settings.file_post_name,"\n","\t","post_params: ",this.settings.post_params.toString(),"\n","\t","file_types: ",this.settings.file_types,"\n","\t","file_types_description: ",this.settings.file_types_description,"\n","\t","file_size_limit: ",this.settings.file_size_limit,"\n","\t","file_upload_limit: ",this.settings.file_upload_limit,"\n","\t","file_queue_limit: ",this.settings.file_queue_limit,"\n","\t","debug: ",this.settings.debug.toString(),"\n","\t","prevent_swf_caching: ",this.settings.prevent_swf_caching.toString(),"\n","\t","button_placeholder_id: ",this.settings.button_placeholder_id.toString(),"\n","\t","button_placeholder: ",(this.settings.button_placeholder?"Set":"Not Set"),"\n","\t","button_image_url: ",this.settings.button_image_url.toString(),"\n","\t","button_width: ",this.settings.button_width.toString(),"\n","\t","button_height: ",this.settings.button_height.toString(),"\n","\t","button_text: ",this.settings.button_text.toString(),"\n","\t","button_text_style: ",this.settings.button_text_style.toString(),"\n","\t","button_text_top_padding: ",this.settings.button_text_top_padding.toString(),"\n","\t","button_text_left_padding: ",this.settings.button_text_left_padding.toString(),"\n","\t","button_action: ",this.settings.button_action.toString(),"\n","\t","button_disabled: ",this.settings.button_disabled.toString(),"\n","\t","custom_settings: ",this.settings.custom_settings.toString(),"\n","Event Handlers:\n","\t","swfupload_loaded_handler assigned: ",(typeof this.settings.swfupload_loaded_handler==="function").toString(),"\n","\t","file_dialog_start_handler assigned: ",(typeof this.settings.file_dialog_start_handler==="function").toString(),"\n","\t","file_queued_handler assigned: ",(typeof this.settings.file_queued_handler==="function").toString(),"\n","\t","file_queue_error_handler assigned: ",(typeof this.settings.file_queue_error_handler==="function").toString(),"\n","\t","upload_start_handler assigned: ",(typeof this.settings.upload_start_handler==="function").toString(),"\n","\t","upload_progress_handler assigned: ",(typeof this.settings.upload_progress_handler==="function").toString(),"\n","\t","upload_error_handler assigned: ",(typeof this.settings.upload_error_handler==="function").toString(),"\n","\t","upload_success_handler assigned: ",(typeof this.settings.upload_success_handler==="function").toString(),"\n","\t","upload_complete_handler assigned: ",(typeof this.settings.upload_complete_handler==="function").toString(),"\n","\t","debug_handler assigned: ",(typeof this.settings.debug_handler==="function").toString(),"\n"].join(""))};SWFUpload.prototype.addSetting=function(b,c,a){if(c==undefined){return(this.settings[b]=a)}else{return(this.settings[b]=c)}};SWFUpload.prototype.getSetting=function(a){if(this.settings[a]!=undefined){return this.settings[a]}return""};SWFUpload.prototype.callFlash=function(functionName,argumentArray){argumentArray=argumentArray||[];var movieElement=this.getMovieElement();var returnValue,returnString;try{returnString=movieElement.CallFunction(''+__flash__argumentsToXML(argumentArray,0)+"");returnValue=eval(returnString)}catch(ex){throw"Call to "+functionName+" failed"}if(returnValue!=undefined&&typeof returnValue.post==="object"){returnValue=this.unescapeFilePostParams(returnValue)}return returnValue};SWFUpload.prototype.selectFile=function(){this.callFlash("SelectFile")};SWFUpload.prototype.selectFiles=function(){this.callFlash("SelectFiles")};SWFUpload.prototype.startUpload=function(a){this.callFlash("StartUpload",[a])};SWFUpload.prototype.cancelUpload=function(a,b){if(b!==false){b=true}this.callFlash("CancelUpload",[a,b])};SWFUpload.prototype.stopUpload=function(){this.callFlash("StopUpload")};SWFUpload.prototype.getStats=function(){return this.callFlash("GetStats")};SWFUpload.prototype.setStats=function(a){this.callFlash("SetStats",[a])};SWFUpload.prototype.getFile=function(a){if(typeof(a)==="number"){return this.callFlash("GetFileByIndex",[a])}else{return this.callFlash("GetFile",[a])}};SWFUpload.prototype.addFileParam=function(a,b,c){return this.callFlash("AddFileParam",[a,b,c])};SWFUpload.prototype.removeFileParam=function(a,b){this.callFlash("RemoveFileParam",[a,b])};SWFUpload.prototype.setUploadURL=function(a){this.settings.upload_url=a.toString();this.callFlash("SetUploadURL",[a])};SWFUpload.prototype.setPostParams=function(a){this.settings.post_params=a;this.callFlash("SetPostParams",[a])};SWFUpload.prototype.addPostParam=function(a,b){this.settings.post_params[a]=b;this.callFlash("SetPostParams",[this.settings.post_params])};SWFUpload.prototype.removePostParam=function(a){delete this.settings.post_params[a];this.callFlash("SetPostParams",[this.settings.post_params])};SWFUpload.prototype.setFileTypes=function(a,b){this.settings.file_types=a;this.settings.file_types_description=b;this.callFlash("SetFileTypes",[a,b])};SWFUpload.prototype.setFileSizeLimit=function(a){this.settings.file_size_limit=a;this.callFlash("SetFileSizeLimit",[a])};SWFUpload.prototype.setFileUploadLimit=function(a){this.settings.file_upload_limit=a;this.callFlash("SetFileUploadLimit",[a])};SWFUpload.prototype.setFileQueueLimit=function(a){this.settings.file_queue_limit=a;this.callFlash("SetFileQueueLimit",[a])};SWFUpload.prototype.setFilePostName=function(a){this.settings.file_post_name=a;this.callFlash("SetFilePostName",[a])};SWFUpload.prototype.setUseQueryString=function(a){this.settings.use_query_string=a;this.callFlash("SetUseQueryString",[a])};SWFUpload.prototype.setRequeueOnError=function(a){this.settings.requeue_on_error=a;this.callFlash("SetRequeueOnError",[a])};SWFUpload.prototype.setHTTPSuccess=function(a){if(typeof a==="string"){a=a.replace(" ","").split(",")}this.settings.http_success=a;this.callFlash("SetHTTPSuccess",[a])};SWFUpload.prototype.setAssumeSuccessTimeout=function(a){this.settings.assume_success_timeout=a;this.callFlash("SetAssumeSuccessTimeout",[a])};SWFUpload.prototype.setDebugEnabled=function(a){this.settings.debug_enabled=a;this.callFlash("SetDebugEnabled",[a])};SWFUpload.prototype.setButtonImageURL=function(a){if(a==undefined){a=""}this.settings.button_image_url=a;this.callFlash("SetButtonImageURL",[a])};SWFUpload.prototype.setButtonDimensions=function(c,a){this.settings.button_width=c;this.settings.button_height=a;var b=this.getMovieElement();if(b!=undefined){b.style.width=c+"px";b.style.height=a+"px"}this.callFlash("SetButtonDimensions",[c,a])};SWFUpload.prototype.setButtonText=function(a){this.settings.button_text=a;this.callFlash("SetButtonText",[a])};SWFUpload.prototype.setButtonTextPadding=function(b,a){this.settings.button_text_top_padding=a;this.settings.button_text_left_padding=b;this.callFlash("SetButtonTextPadding",[b,a])};SWFUpload.prototype.setButtonTextStyle=function(a){this.settings.button_text_style=a;this.callFlash("SetButtonTextStyle",[a])};SWFUpload.prototype.setButtonDisabled=function(a){this.settings.button_disabled=a;this.callFlash("SetButtonDisabled",[a])};SWFUpload.prototype.setButtonAction=function(a){this.settings.button_action=a;this.callFlash("SetButtonAction",[a])};SWFUpload.prototype.setButtonCursor=function(a){this.settings.button_cursor=a;this.callFlash("SetButtonCursor",[a])};SWFUpload.prototype.queueEvent=function(b,c){if(c==undefined){c=[]}else{if(!(c instanceof Array)){c=[c]}}var a=this;if(typeof this.settings[b]==="function"){this.eventQueue.push(function(){this.settings[b].apply(this,c)});setTimeout(function(){a.executeNextEvent()},0)}else{if(this.settings[b]!==null){throw"Event handler "+b+" is unknown or is not a function"}}};SWFUpload.prototype.executeNextEvent=function(){var a=this.eventQueue?this.eventQueue.shift():null;if(typeof(a)==="function"){a.apply(this)}};SWFUpload.prototype.unescapeFilePostParams=function(c){var e=/[$]([0-9a-f]{4})/i;var f={};var d;if(c!=undefined){for(var a in c.post){if(c.post.hasOwnProperty(a)){d=a;var b;while((b=e.exec(d))!==null){d=d.replace(b[0],String.fromCharCode(parseInt("0x"+b[1],16)))}f[d]=c.post[a]}}c.post=f}return c};SWFUpload.prototype.testExternalInterface=function(){try{return this.callFlash("TestExternalInterface")}catch(a){return false}};SWFUpload.prototype.flashReady=function(){var a=this.getMovieElement();if(!a){this.debug("Flash called back ready but the flash movie can't be found.");return}this.cleanUp(a);this.queueEvent("swfupload_loaded_handler")};SWFUpload.prototype.cleanUp=function(a){try{if(this.movieElement&&typeof(a.CallFunction)==="unknown"){this.debug("Removing Flash functions hooks (this should only run in IE and should prevent memory leaks)");for(var c in a){try{if(typeof(a[c])==="function"){a[c]=null}}catch(b){}}}}catch(d){}window.__flash__removeCallback=function(e,f){try{if(e){e[f]=null}}catch(g){}}};SWFUpload.prototype.fileDialogStart=function(){this.queueEvent("file_dialog_start_handler")};SWFUpload.prototype.fileQueued=function(a){a=this.unescapeFilePostParams(a);this.queueEvent("file_queued_handler",a)};SWFUpload.prototype.fileQueueError=function(a,c,b){a=this.unescapeFilePostParams(a);this.queueEvent("file_queue_error_handler",[a,c,b])};SWFUpload.prototype.fileDialogComplete=function(b,c,a){this.queueEvent("file_dialog_complete_handler",[b,c,a])};SWFUpload.prototype.uploadStart=function(a){a=this.unescapeFilePostParams(a);this.queueEvent("return_upload_start_handler",a)};SWFUpload.prototype.returnUploadStart=function(a){var b;if(typeof this.settings.upload_start_handler==="function"){a=this.unescapeFilePostParams(a);b=this.settings.upload_start_handler.call(this,a)}else{if(this.settings.upload_start_handler!=undefined){throw"upload_start_handler must be a function"}}if(b===undefined){b=true}b=!!b;this.callFlash("ReturnUploadStart",[b])};SWFUpload.prototype.uploadProgress=function(a,c,b){a=this.unescapeFilePostParams(a);this.queueEvent("upload_progress_handler",[a,c,b])};SWFUpload.prototype.uploadError=function(a,c,b){a=this.unescapeFilePostParams(a);this.queueEvent("upload_error_handler",[a,c,b])};SWFUpload.prototype.uploadSuccess=function(b,a,c){b=this.unescapeFilePostParams(b);this.queueEvent("upload_success_handler",[b,a,c])};SWFUpload.prototype.uploadComplete=function(a){a=this.unescapeFilePostParams(a);this.queueEvent("upload_complete_handler",a)};SWFUpload.prototype.debug=function(a){this.queueEvent("debug_handler",a)};SWFUpload.prototype.debugMessage=function(c){if(this.settings.debug){var a,d=[];if(typeof c==="object"&&typeof c.name==="string"&&typeof c.message==="string"){for(var b in c){if(c.hasOwnProperty(b)){d.push(b+": "+c[b])}}a=d.join("\n")||"";d=a.split("\n");a="EXCEPTION: "+d.join("\nEXCEPTION: ");SWFUpload.Console.writeLine(a)}else{SWFUpload.Console.writeLine(c)}}};SWFUpload.Console={};SWFUpload.Console.writeLine=function(d){var b,a;try{b=document.getElementById("SWFUpload_Console");if(!b){a=document.createElement("form");document.getElementsByTagName("body")[0].appendChild(a);b=document.createElement("textarea");b.id="SWFUpload_Console";b.style.fontFamily="monospace";b.setAttribute("wrap","off");b.wrap="off";b.style.overflow="auto";b.style.width="700px";b.style.height="350px";b.style.margin="5px";a.appendChild(b)}b.value+=d+"\n";b.scrollTop=b.scrollHeight-b.clientHeight}catch(c){alert("Exception: "+c.name+" Message: "+c.message)}}; + +/* +Uploadify v3.0.0 +Copyright (c) 2010 Ronnie Garcia + +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. +*/ + +if(jQuery){(function(a){a.extend(a.fn,{uploadify:function(b,c){a(this).each(function(){var r=a(this).clone();var k=a.extend({id:a(this).attr("id"),swf:"uploadify.swf",uploader:"uploadify.php",auto:false,buttonClass:"",buttonCursor:"hand",buttonImage:false,buttonText:"SELECT FILES",cancelImage:"uploadify-cancel.png",checkExisting:"uploadify-check-existing.php",debug:false,fileObjName:"Filedata",fileSizeLimit:0,fileTypeDesc:"All Files (*.*)",fileTypeExts:"*.*",height:30,method:"post",multi:false,queueID:false,queueSizeLimit:999,removeCompleted:true,removeTimeout:3,requeueErrors:true,postData:{},preventCaching:true,progressData:"percentage",successTimeout:30,transparent:true,uploadLimit:999,uploaderType:"html5",width:120,skipDefault:[],onClearQueue:function(){},onDialogOpen:function(){},onDialogClose:function(){},onInit:function(){},onQueueComplete:function(){},onSelectError:function(){},onSelect:function(){},onSWFReady:function(){},onUploadCancel:function(){},onUploadComplete:function(){},onUploadError:function(){},onUploadProgress:function(){},onUploadStart:function(){}},b);var d={assume_success_timeout:k.successTimeout,button_placeholder_id:k.id,button_image_url:k.buttonImage,button_width:k.width,button_height:k.height,button_text:null,button_text_style:null,button_text_top_padding:0,button_text_left_padding:0,button_action:(k.multi?SWFUpload.BUTTON_ACTION.SELECT_FILES:SWFUpload.BUTTON_ACTION.SELECT_FILE),button_disabled:false,button_cursor:(k.buttonCursor=="arrow"?SWFUpload.CURSOR.ARROW:SWFUpload.CURSOR.HAND),button_window_mode:(k.transparent&&!k.buttonImage?SWFUpload.WINDOW_MODE.TRANSPARENT:SWFUpload.WINDOW_MODE.OPAQUE),debug:k.debug,requeue_on_error:k.requeueErrors,file_post_name:k.fileObjName,file_size_limit:k.fileSizeLimit,file_types:k.fileTypeExts,file_types_description:k.fileTypeDesc,file_queue_limit:k.queueSizeLimit,file_upload_limit:k.uploadLimit,flash_url:k.swf,prevent_swf_caching:k.preventCaching,post_params:k.postData,upload_url:k.uploader,use_query_string:(k.method=="get"),file_dialog_complete_handler:e,file_dialog_start_handler:t,file_queued_handler:p,file_queue_error_handler:q,flash_ready_handler:k.onSWFReady,upload_complete_handler:i,upload_error_handler:s,upload_progress_handler:g,upload_start_handler:h,upload_success_handler:n};if(c){d=a.extend(d,c)}d=a.extend(d,k);window["uploadify_"+k.id]=new SWFUpload(d);var j=window["uploadify_"+k.id];j.original=r;var f=a("
",{id:k.id,"class":"uploadify",css:{height:k.height+"px",position:"relative",width:k.width+"px"}});a("#"+j.movieName).wrap(f);if(!k.queueID){var m=a("
",{id:k.id+"_queue","class":"uploadifyQueue"});a("#"+k.id).after(m);j.settings.queueID=k.queueID=k.id+"_queue"}j.queue={files:{},filesSelected:0,filesQueued:0,filesReplaced:0,filesCancelled:0,filesErrored:0,averageSpeed:0,queueLength:0,queueSize:0,uploadSize:0,queueBytesUploaded:0,uploadQueue:[],errorMsg:"Some files were not added to the queue:"};if(!k.buttonImage){var l=a("
",{id:k.id+"_button","class":"uploadifyButton "+k.buttonClass,html:''+k.buttonText+""});a("#"+k.id).append(l);a("#"+j.movieName).css({position:"absolute","z-index":1})}else{a("#"+j.movieName).addClass(k.buttonClass)}function e(u,w,x){var v=j.getStats();j.queue.filesErrored=u-w;j.queue.filesSelected=u;j.queue.filesQueued=w-j.queue.filesCancelled;j.queue.queueLength=x;if(a.inArray("onDialogClose",j.settings.skipDefault)<0){if(j.queue.filesErrored>0){alert(j.queue.errorMsg)}}if(j.settings.onDialogClose){j.settings.onDialogClose(j.queue)}if(j.settings.auto){a("#"+j.settings.id).uploadifyUpload("*")}}function t(){j.queue.errorMsg="Some files were not added to the queue:";j.queue.filesReplaced=0;j.queue.filesCancelled=0;if(j.settings.onDialogOpen){j.settings.onDialogOpen()}}function p(w){if(a.inArray("onSelect",j.settings.skipDefault)<0){var v={};for(var B in j.queue.files){v=j.queue.files[B];if(v.name==w.name){var x=confirm('The file named "'+w.name+'" is already in the queue.\nDo you want to replace the existing item in the queue?');if(!x){j.cancelUpload(w.id);j.queue.filesCancelled++;return false}else{a("#"+v.id).remove();j.cancelUpload(v.id);j.queue.filesReplaced++}}}var u=Math.round(w.size/1024);var z="KB";if(u>1000){u=Math.round(u/1000);z="MB"}var y=u.toString().split(".");u=y[0];if(y.length>1){u+="."+y[1].substr(0,2)}u+=z;var A=w.name;if(A.length>25){A=A.substr(0,25)+"..."}a("#"+j.settings.queueID).append('
'+A+" ("+u+')
');j.queue.queueSize+=w.size}j.queue.files[w.id]=w;if(j.settings.onSelect){j.settings.onSelect(w)}}function q(u,w,v){if(a.inArray("onSelectError",j.settings.skipDefault)<0){switch(w){case SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED:if(j.settings.queueSizeLimit>v){j.queue.errorMsg+="\nThe number of files selected exceeds the remaining upload limit ("+v+")."}else{j.queue.errorMsg+="\nThe number of files selected exceeds the queue size limit ("+j.settings.queueSizeLimit+")."}break;case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT:j.queue.errorMsg+='\nThe file "'+u.name+'" exceeds the size limit ('+j.settings.fileSizeLimit+").";break;case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:j.queue.errorMsg+='\nThe file "'+u.name+'" is empty.';break;case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT:j.queue.errorMsg+='\nThe file "'+u.name+'" is not an accepted file type ('+j.settings.fileTypeDesc+").";break}}if(w!=SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED){delete j.queue.files[u.id]}if(j.settings.onSelectError){j.settings.onSelectError(u,w,v)}}function o(){var u=j.getStats();if(j.settings.onQueueComplete){j.settings.onQueueComplete(u)}}function i(v){var u=j.getStats();j.queue.queueLength=u.files_queued;if(j.queue.uploadQueue[0]=="*"){if(j.queue.queueLength>0){j.startUpload()}else{j.queue.uploadQueue=[];if(j.settings.onQueueComplete){j.settings.onQueueComplete(u)}}}else{if(j.queue.uploadQueue.length>0){j.startUpload(j.queue.uploadQueue.shift())}else{j.queue.uploadQueue=[];if(j.settings.onQueueComplete){setting.onQueueComplete(u)}}}if(a.inArray("onUploadComplete",j.settings.skipDefault)<0){if(j.settings.removeCompleted){switch(v.filestatus){case SWFUpload.FILE_STATUS.COMPLETE:setTimeout(function(){if(a("#"+v.id)){j.queue.queueSize-=v.size;delete j.queue.files[v.id];a("#"+v.id).fadeOut(500,function(){a(this).remove()})}},j.settings.removeTimeout*1000);break;case SWFUpload.FILE_STATUS.ERROR:if(!j.settings.requeueErrors){setTimeout(function(){if(a("#"+v.id)){j.queue.queueSize-=v.size;delete j.queue.files[v.id];a("#"+v.id).fadeOut(500,function(){a(this).remove()})}},j.settings.removeTimeout*1000)}break}}}if(j.settings.onUploadComplete){j.settings.onUploadComplete(v,j.queue)}}function s(u,x,w){var v="Error";if(x!=SWFUpload.UPLOAD_ERROR.FILE_CANCELLED&&x!=SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED){a("#"+u.id).addClass("uploadifyError")}a("#"+u.id).find(".uploadifyProgressBar").css("width","1px");switch(x){case SWFUpload.UPLOAD_ERROR.HTTP_ERROR:v="HTTP Error ("+w+")";break;case SWFUpload.UPLOAD_ERROR.MISSING_UPLOAD_URL:v="Missing Upload URL";break;case SWFUpload.UPLOAD_ERROR.IO_ERROR:v="IO Error";break;case SWFUpload.UPLOAD_ERROR.SECURITY_ERROR:v="Security Error";break;case SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED:alert("The upload limit has been reached ("+w+").");v="Exceeds Upload Limit";break;case SWFUpload.UPLOAD_ERROR.UPLOAD_FAILED:v="Failed";break;case SWFUpload.UPLOAD_ERROR.SPECIFIED_FILE_ID_NOT_FOUND:break;case SWFUpload.UPLOAD_ERROR.FILE_VALIDATION_FAILED:v="Validation Error";break;case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED:v="Cancelled";j.queue.queueSize-=u.size;if(u.status==SWFUpload.FILE_STATUS.IN_PROGRESS||a.inArray(u.id,j.queue.uploadQueue)>=0){j.queue.uploadSize-=u.size}delete j.queue.files[u.id];break;case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED:v="Stopped";break}if(x!=SWFUpload.UPLOAD_ERROR.SPECIFIED_FILE_ID_NOT_FOUND&&u.status!=SWFUpload.FILE_STATUS.COMPLETE){a("#"+u.id).find(".data").html(" - "+v)}if(j.settings.onUploadError){j.settings.onUploadError(u,x,w,v,j.queue)}}function g(x,C,z){var v=new Date();var D=v.getTime();var A=D-j.timer;j.timer=D;var y=C-j.bytesLoaded;j.bytesLoaded=C;var u=j.queue.queueBytesUploaded+C;var F=Math.round(C/z*100);var B=0;var w=(y/1024)/(A/1000);w=Math.floor(w*10)/10;if(j.queue.averageSpeed>0){j.queue.averageSpeed=(j.queue.averageSpeed+w)/2}else{j.queue.averageSpeed=w}if(w>1000){B=(w*0.001);j.queue.averageSpeed=B}var E="KB/s";if(B>0){E="MB/s"}if(a.inArray("onUploadProgress",j.settings.skipDefault)<0){if(j.settings.progressData=="percentage"){a("#"+x.id).find(".data").html(" - "+F+"%")}else{if(j.settings.progressData=="speed"){a("#"+x.id).find(".data").html(" - "+F+E)}}a("#"+x.id).find(".uploadifyProgressBar").css("width",F+"%")}if(j.settings.onUploadProgress){j.settings.onUploadProgress(x,C,z,u,j.queue.uploadSize)}}function h(u){var v=new Date();j.timer=v.getTime();j.bytesLoaded=0;if(j.queue.uploadQueue.length==0){j.queue.uploadSize=u.size}if(j.settings.checkExisting!==false){a.ajax({type:"POST",async:false,url:j.settings.checkExisting,data:{filename:u.name},success:function(x){if(x==1){var w=confirm('A file with the name "'+u.name+'" already exists on the server.\nWould you like to replace the existing file?');if(!w){j.cancelUpload(u.id);a("#"+u.id).remove();if(j.queue.uploadQueue.length>0&&j.queue.queueLength>0){if(j.queue.uploadQueue[0]=="*"){j.startUpload()}else{j.startUpload(j.queue.uploadQueue.shift())}}}}}})}if(j.settings.onUploadStart){j.settings.onUploadStart(u)}}function n(v,w,u){j.queue.queueBytesUploaded+=v.size;a("#"+v.id).find(".data").html(" - Complete");if(j.settings.onUploadSuccess){j.settings.onUploadSuccess(v,w,u)}}})},uploadifyCancel:function(b){var f=a(this).selector.replace("#","");var d=window["uploadify_"+f];var c=-1;if(arguments[0]){if(arguments[0]=="*"){a("#"+d.settings.queueID).find(".uploadifyQueueItem").each(function(){c++;d.cancelUpload(a(this).attr("id"));a(this).delay(100*c).fadeOut(500,function(){a(this).remove()})});d.queue.queueSize=0}else{for(var e=0;eKLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z0002HNklN^?6|u>+2=S^WJsP6GfSV=^g`)~J*K0000h5t|IV(Yk>pE~otwY{CWoUqCQu+Igg8DDhr|j# z!s$3GX*U+gmMh6QcxefNa1;szNGMRi+>|R^<)(#lm!q;>k{*=aExk|La{B!~GrN); zCw$)b_x|xSeRk)WdFGjCo_XeZo|#oTpp-nRD9>zFDwxs~oTezsd6jQ4MOmDVTlMWt zE&ArZWPhd}*a@?Hv)O_A1q(K9+ElygsM=I|!-69hEn2joZsCH33+IDker8L5*4RA1 zKXdr(C4xbdnTe$n1KC8XUnks%rUtVo%${v?jmPp#2L{tg!7?6OU?$Bzvp<_zaAfU~ zU=)wlTd8!PkzHa83?vgVgV-(DJU`Q$ik-d5*l5nTl18R?@qz*&^~ol(NpndL6;Ow)1cn9u~grJfpjW97=ug}Sc%TXU5LfNU^JP?^qT1< zgZ*dsr#8tU3bjNNOPfYEHJ-w$qxPiHzhThWU@mEH6K#21$Y^BEC993JzVO(vzOb%t zkrab!7cbaH+jb2WaEa0scwbwrG^%4`W2gHytgr{5DGgpl{5^I1-&g2Z@$dROPHE{H zNT!Uq^6jc8)+q`q6)SD@nMW!CrB;~^24fXpr^jdXxSAfylPFg_NDuZIJujlid!OQQ z3AJBE=-&ywgG!%J>3w?KK(2pqXxyG&FX$;?>c- zs=2YVr=@jObH@}p180@;QbMFeGTzfKv{^w~TC*zB(4;S{U07RJ3IT|D=avC8Qzo=K zXi7D@o6P9ohCpMgZy;%A&7KuTe>`cXgXpnL%&WBzy9aAhVe_Dgw85f-wCZ9}oj!h= zbWfr`Zf-7(44C~+eW@6($0XWJ3HgSO!B`B!`z%MM(q$yQz3d@O4BOenl3+E21(wLg z9?T|^8MmmZu#LzEwkhS8-l3dS zw25eudjuYYdNHZ2)E+iLU%^Hkv-fu(@WjM0C$fgFQCd$*&q$B-e^-0gdteg9VSmkj-^7E?_X6$Sr zTc@G?WJsKj?3ScC8C8P=6C4BYXg$5TCvuX#dbA&;D=QHSmlDk^(&6gXj*iy0_97am|*Fp#jd@o$d8NY*o6FI+Qh*+IwNb=G&dEuoZj4y>7LfvEGAb) z3o4dTuBcE_X`|TWavqZhi#KpyoWqJ(5+gfob@T|8ib$qUlxLp^m-nefxlDOjc}e2h#mrg|Jz)lf^En8nXpUj7?FN0WbXzzsXUo*PVJ@< z-%=Q14K|zfDy{uiiXy613iLTyc;E?^SJ`W1sJj_&$@8lmAN(62!708$hf$TWpN&=` z=Y2{dp6#v3jGtJgEj)!DNBSwYu{%MfIHb3a^ONOYl%YnBp9!wQlMJ?bv+XHn73r&E zO><*wOKY>-z&+T=Z4rdTNLO1^x#I_Af>Umd3p1e!lMFk_uW9>QUt>dCWAmz2<9ByQGghm$ z^EBIDGEyRIFzG0+qR4YZuso%XDbVVNI#Vl+jYfyqi!x9M1@)wz5LY6zKcPG?9KR@( zEtff??BUI(q@LU&y($q5G9u;HV3ukk?mH{flM=N4fqXYtpONSALw~UJbC6b*;?(H$9%%PSE9ylPAhGFy<{^m&~GmerKNY*L$=QnY%mbSjlCX>RLmZtrPnZ&=+N zfH{v#iaatq^+>I`VHF!p9v)8b(vX~L;H5)R^64^duz}GjJ#7QF2Z+bVS((zN$ z#(+O-MD390CwIRgjfIbUqG-m!CL_EowU$9Aad=1blwPF3-VNy5n}}t6QFB9rf_>5( zPaB)sLCsB()g^7KAPjc*QS4fj1;>eojKILF)7@ZG;|!bU}0U|F$?Himre9n zjXUnv%X4V;_{t{vmOH%>iwFBL(}#>F62^($l-Ovygc+a18}et9F|_xh+JnX3j4hS@T0*_HB@~Lo9huPmJt^q2v>$yQ(NO}NG5f0AaP~W zgQlHoIVYkic^&Dk{fVsZjP34hUESPHn>C$P&CR}esx6i6g|j?lf)IMzOrR^Y0Yi?L z&~CGHl4(vMqi@1`n0kLIt7pt?z0UijQ+Eqp948j8UZ1GddLg+kEA>qXE~!m={y17Y z+wM4C)B2pqn&!5-cHh>fdfkww}_#y zR$oROL`krz*C*SZ#^nX|`XTxN5)3mA>9f5^mvosTL2H=-q%fw77V4031LphY$E(uY zZE_T1CiX@gO4KROs@FX-(0Y<)|AuUDjm?U7tk7<~-kCP~Gf4xxbb~Hw^%%Ch9@Mj` z@k8?HU^Gf+SE*w%k(zO$*&NBe%2Z!3lCq*!HpsiSdY#qIo!A*2S|hqs%=ay=%~xZ+ z=-hqOe)~F6XgmjbNms9z*V^^OpkDWqMNu3&Rpz0(ouJj{wWw!%O<{K#T{=-zS?N@t zsE-S?tJPruq#RP8L#`*mwYIi)PLb&rT!fI*<|ekDK1ZLco10^%8P8zlDR2@u(L*QW z)aR&kYsFQJTp-uLV5WEGzRcsr8awhpLkkMpYAH)MbaADmQ>3arRJ0^AqS5HrMHr_E zQ?;O|`&^#R1cbmz%AIRvgQ##?9j=mK-sf_JEa#Z%lrFYoZOz0wh#991PZCE>+ZM3% zm;cY%>Zl)gWkb!0exaAzrTeEZjA)2`f$1DTkTnPNT|$_C`Z5sL2MQKcFf&^0TH8LH z+Il_URLK>u*H=v#K|~m^7uQ$B(`MCyGG-%9uU2o^cX_cTMV1VJ@AgE+?N>=N)=iwk z>-B@}wUc*fqDxQFN089O=9B)%!mXy9=5uB9NTD?5LGjz=Oo`RoB`zpxwB z)+YNvpm)f|@lM=Xm7*>)3m0^A=1yR}czkPHO3DgTu`e2vTkI~FWUX$8NAjrgRPD_D z$(|p0daa&6{W{!i(#e9zo=Bdk_F$V|tmu-ah~c6GGlW$P4h*EF4Hvsoku%j!+OLzH zR?JTx!fgt1rYbbL#Y*{*ikcR3xwuE(?;|47!Kx(D-!otbPjRJ~k@w7T_3Wsp-Q3W; zdBC^s%uLO>fa;QLY86Z(-DqS?o;H!=#Z1?_Gvo8zeU#35k=kTTBpvQVrp;(8ofAFx z?C80D(Q`LM=d!5U7gaYzna;v)WQU3Dp^d4*WL)~Wc-)RkGQ^3{2V;|mQLj9F*Xu!w zm-dmhhe$G^;u?EGMOBqWw03jGMJfu&467$Ww^==d>7;uTU5$8p#SN%mTuOEHnr2o` zsj;KOpDEP!X8V$KSSTCJm=vw#-QV(}t6Q>0+dzzDnvz&}Gu_d%utZ(tZDfuHRDjgW zF@~}tKFD4222|OSNN2LPh4;%PZ{4qH*dq()jz~twmN<>6_odQKB!!iZ^O1*j_Bxo| zvDe6e!tBp;IC8&(+46~XwCKQ-7Y=#Vej6!13xfQXDN4$VqvyPRG-~hf%>GyWU~>jLIglEx5T*l z)#`eOV{G;k!v$(E`*J~*SGY&E&Ym!Qy`GOidMYNo7bUmi^0&2#`Ca{Vk+wnHvc}Fv zE*mo!O|+JxUD0CD@uzmbY}f49&gh&{lnaX$P766{u0}Fr%59Zj(tI9R`-KDd-G5Kf zt7E^h>Hj84saP`m&X1?%x60ZB4P@&owgu-$xI{ZRmf&EV6`uwomM1e9h4GZah}IhE z1f2ykfx^e{)h3QJao3tiN2jMxl!MEYsi=_@R!5)TaR4}>96LR-sUI2ifSJy2@tETF zDVRc&!CH59hc_?D?ccJT#6m-mNu`_wh$&SkG@Pm6IyGr%bk1(XoKq-~-Tj{u)z>0k?Xv)UjgF%%=~g!+JnPOtv71%9>hR}}^&06$$k&i%JubR) zE)~DSfp&3hHeK|{*U;U5pf43qSoV*Hn)aSVVv`3sZROx?|<`rQhUJ#6xim|O8)sZO6f{VH|(4t4s~>hx>W>DQ{$18!yd zZZuB!yURJ#)IiV^s;rs>Hr_H8oTmAwPxY2EEjXj(ps7r|RpU(Ms*9^`&OBV@T=jC* z$2C7^C0s4#Y8h9-r-HKpXF=|&lacd^zVUIB(^ACFdt`zKZkJoVRfv z;l7hOZ|A&&^G?pYIA6>8DV(3m`DvV=&iNUfpUHVQ=j%A{;e0*k2Io=EW1Po1H#xUB z-@th<=Lycw;{0sRlbrW)-p_f8^8wDk$a$Lc4Ch(S2RYx!`6kXcbH0W1b2$Gm&d=ri zOPqh1^Yb|0$~ZqCunlkl;6lK5z(s(I0ha(S1$+f?8Q^ljR{>W5t^`~K*a5g2a1G#E zz)rv}z;%GH0j>w!0JstGb-+!4n*p}~h5)w$ZUfv7xC3w};4Z-3fO`PnVBCE#-uD6S z2Rs0Hka2A{;=5O19%be65wStzXEs_<++?K;_Njrcpcbx0dD}_1iS@!8}L0q4loR%MgXHIe;@C6 z7%$(8@(%z%WW3_Xc>e_O9^j{dp8062~LW-{O5%(oTD zy+!w;?;8PM*SPN{yl)2F0vH02 z<9h(`AYeD(A;4pR$2H%1%y$y=JwYQsiJGSY&uG3B^L>%|7GWsZxArK+eI7%+0Fhn< zyrgm0%Yauv{3_rz)V+cCn|OZ@FbvoM{QKzh4qy*pFYw=^{ttNnQRC{LH17U0;4gr` zqV8|n40VR)`%u%MBF*TGF0_H>2P*htk80SH+W9Wu z$LQmC^@<;DvH~!s9_XRjREnaCw@cuvXs{n{dU*1vC~-y6nAhi0ysV^zF+bIn(4#a@ zCmv;zoekjYbfIySaw4HexsM(dVCwSuP*z>^giYE6=vTli@(+Q!@(-eu4KCTLib=|W zD=HMP$~64P99E*zp)Tg?W%TEw{?u0C#luCvg$>wzg;FbskGCL~c-X&~6$>E8@IihT z^HtCs=}lwiYs-T{`G#KdRI=5cv&&~MkVMPMNK@s?xIfXP_!Q_om?^UlLCK}* zM0}`6@y%j~F{S2krW{($l%^w?QaOt$N6%(T?Hr~|nX4#eN)1y2^U%w!g$bQcU2B=r zxIj_rlp~okbs_u8SS+}lKn#{JWzvaE znY@%K4GmPWj4AUQsn7%>kJhXx-qO+*rX0VVDKl3nN~pB7RZ&(dCoyH^DyAH~nkk30 zVUB)(gega@p`Ir*CD_iCMIB5j?-WCIk%_Kl%92xna_v;2I*lpIPiM-kGnjJZnSwz# zX=xo(=Jhb;*!4^~$Y9E0QL2nFWnr8;nZUf7g{M#3z?3iaQe{GnaTcC_?QEu$C8@HH z`t_6YQz(^a19+BdUt~&4nkjmQNU~xH2JtM@Hd4hVdTbWlwlHP!In?{Vm~!H|RR1NW z)PI>N$DJn_ZG|aSlxv74%Hi7>wO=5f7g9ab5HOUgi>O?oU5xUKOGGPTiPHQPJmy@6 zN9pBE%=@dd&lQ5?N+!m?ieAbNJnKqJuLkk-Yw)N*cv0$hN)p5?WyN(=4rpIPx%GNk ze}n9FBdQjB9gkyf!XtFE;C>5=%MkdK>RZJCx8Zp^Q|=%nsNG4gkam~kb2mw++ykHD zSI$(t<-QWdDES8Zn)jk5q}+#M?0!6=58x4h5D#m&oXSIZJLoAa({gpo zg_HOCe7U;ZGG%M!JIjTW_xl+Nnx^^vhj+itYTmKlW;<&3438LZGq37p)$wvTv2|~= zY6UeQb*ZY~U$OpsEb?`x;58iCK-F%lE(bo#=(ihD>v3vl7uRyCol1SJ91{(*jJsK( z-AnD0^1Wt{YxI3yqaVS??_EF4B9{rg#I5<~-(8WbJEi8GI+N*JEBiG0a;-bAd(p~8 zO7C&&>buKUmMOjU>*mVB+;vCG!qMx(Yn9$`u2osTXje@TK6&o?kW&bt;HJU|L&+;k z)+iyI5N>^+?FzwMmal(@h2Le7J&c*q;$R-^Slit65FR3G^*iIpS82;QpoK3nR_kE>e0V@usd=+)yJ}^X(mOS0O|{0@{3+E+WUH!5tXiq5W;K!X zRhPsg+f)UmS;hrK03*N9es8C@P{(+cO%)?x39XA%>tfZqMD4wq<-$ABd@~yg?^1_) zFDb&W1Kv(N4D8|2{_MTdVUZ(cWFG4R@!?&wLIcxq<_zrN|Sk&}YH3F}m zvrY{nQOt$!B0ko9iQG+Gtc?=6M@2t0MRtwT?iFhI8|r-_Y_wSc?4{Yg=LC?Yok@0F6gqCkF?+ET%K6FDnU zt(0OgqDtiZszrUTn$UNL=zBdTc|EMF)FXReUl>{|>b^sCw}?8iyCy_#LkxP~t`NKi z6p+Ysy6=F^g|V;RS3PIu)#ECt=V~!%q1QG0_G-)bau<4CGeN1>3Zv5q(aF zFhYbqViEmKg8s_|dVdl9%@ZZOWnT%0goIxzNLW%V;jI%TyiJVQUKp{oXvEtmj(CR{ zU<(UOv+2tm`kZyA8o5jMDA3=%&)P;>SYU?TwcP32?V8=G1$NU$Rpm0OU^Cd4);oXwIm3%;j%S&%9y|WaB zXG?!k`Wq^IR(eg@b!8|#SoUJst5o<|*=J?j%2Bwf{E_mhJD(Wwp@;xM4mC7*E ztV-o=%F>il9IE_B=jsYm4;~JU3B^1l6k}bEOm81;7?)G3REDFN-<7MIg@Z^r60eG% zXfi=T0uf%FvzA95QdKH<zwlO zIqM5fc}31z=9I%ZYqnFq4P0-`bG;GRwRtR>v(9kJXXUJzQ(l|1B2IZ;&YIisv#A_7bl(6Jend6ZB(ok? zha!)tY&o`wSoRCVvM*?<;E}#De2C=Mfs@2K^6fKZy2H*y$ zW^i!Nu=V(ahR4yccVzVb8gdtNN2`^5M7k33XLkrk>6~=~)2EfmLgWeLO1g0a97r9} zU_akh&9I@V3hmg^Ppa#0va?puV^inC&pOixKc^0j428d?4vkKj(#WVilaLG3pGnjI zwn}3Rg`Zc68vds_%w|VU)Id~8L`$&yb}+qC2)Dx#ZU+fh9hYK}t?ppL)8wq}wp=@e zT;NirflDcd609R9s;HYpb>*^d*m_EpwUgZ*pZ`46qO+}y;sN)sqnen@x{K|IxudSA z+qjE)-Co!5dav~cGaiD?d`BG?N_i3LXn9&yhQcqAdK|@MhHbSx&0M+Jk)z0QOmTCc z|23?#zLm#Zv-e;j_XeipNR+d}qt-KE_^dh|`Nyn1feJ+#-7&a#6fM?s>ZBi!jg5pB zQl9mypc)FlCbZhk#W`iz`WC9ct%li3?jqi~s4KFB1x`ngnwZ<#yd&m`x}zRrv)AKw zLp7MjTXGt2s!4s zkG{1$#%IU8b7H>PF@G-neew}lWUS=99qZTqMTeJ4p?QCDe6G1t9t4y7)^VDBi6S~{PM z=^d5IL*YHNrNes*8jI(wNxCrW$hVm*@Fo*Oy8}-##nV8$Im2>&+qy3{q_8X=oxkIz~V*SwAhnQ_-rf}{-wR}zbbZF zNvazu3S~20NN%2FGP%ihhgOCZ0|~$i`?}*|+aa$QcimwkDN*~7HR4D}*BSG{v|6D{ zC?t~B{OyRh*2Zyl8@Gcl{A=_~7S^vpWL(yY?w6=uw5@zeRoAk}%PQMX2!CIM@RnEL zh$)66gfD03T+Mbdirea|$OC=KYpTM0%E2_NtC(}A^#3O9ANDKlasL--+t2EsAnPHN zOk64=M)^DNV0vXnv6F|$>na^6nRjd4CPH5~q{ z^o8NSjc;rmj=YGK4gZ~NDnKXK@IR;so6sqS-Ru&64^D3{33cDDnov+UBl5q)a7`Mp z;a#DP8ADC?** zqfsb-ly>AusD|YEP#qQ0e6)}3qeAkJrQ`uA`Dl^cq{zUl$Q@xRJ|Snzo2p`qxikE! zS_R`1L<(uNUKr$V=`Ba~`+~2Jjg9J+7a?aDr{Vu!Q-PTrsv+Zg28KIlFKYG-?+kyY zP7h-dDu!`D74hhy8VZ4PM`a9oASA-zT*`ycAutosac6i;osNa>KCRm~jAM7pX^fgw z9E(?s=+jP9lo6SByvgpb2_oRlwei>4{UJ#u@z>b2Ss*UjBqL&rP>Q!RpW^KlDc-CV zasWj+tQ6#mpow(s=4Ui1ZRf=jCZih~_*&;v$mGgT`hMEE`X-tU$1M z&{zzDy72^c1%i2l#yqS`wd(fyHXl+qnyKbU zJN*b8BobD+lgK{xN(?~zG3r8?aYbFyKqvixjIs*4)K>_jfkuuXjm(BG#7U+m=qD#3 zSO1#bAwdXim^SEJDv{69-100jELI+?B?OAPkXGN%)LAQNm1e6*4X5XcNFHpK(UHh~ zj7f?)l;RzNbsST%m5_ymJT!6`2?-sXa>K?I^} zVI>V_%+HM&`5R9(&C|R-|NB^NO8COtw7u)!R>K!+%h=Yp)tGCz<$J2K{hi^cE6iGQ zs){1DUySyaVHFuBwx&*l(w0DaB{n$S#&nOUQFpaMN*PhHRNbTMNXw|oHp;ITBXlN| ziQOK-@v&LGw|(ysTfKuZJ{rDUo9-i%1`;?JstbQrRLq}B6=hU$ zg*F|7&7X#f+(?w)X3W5Z!=$f}SWG*$d{mFF{Pzf!98RMak@ zS}xRjCeXS9+6MGUm&admyGj9jkN5~w)`tkIZ>LW|hi>b0nQT~GVH#nIyTWN?C{_~| zzEXq2zptv{tF)GPNG*NP!(Ix~+hEI!Vaq16<M3!*bR5;$ZoM>JQlm>_bNPUwg%G8-AcFnos$mNfrUXgpn9A-jR7Fu)yL}c%ZMCS`M;6ge{P7lr@4%2ehG1I+t zCAVA=H}O<+o~&7`2%i>NMYjOQ&{-`bw%t3l3uy3R@fGMcHX^d@@;fma&DxZR$>v2F;7&V+x=5@*>rd4^ zBSi2s%JN!AjGxN^wlU)uBv!o(9`P{JWovG@X0H()^=d*Pt+^4Pw=%-T1ddnj8zE$?h7^V- zDiYOuwZi3|%xvGJ)IxNbZ0D+xCvf-_+4Fsx%$`ql!Jnu+Ll5RSHHIJ#{o-~DWXy_m~ip^d+( z#FVlaYO}AK{!Z>%3#?Q2b8H*0mckiMoZOx(-WOZN=j`yeq&bGaoo{OtpSf{tTh5OC zk@}uWXGzyT;O)zmf5P+oln>x&UCO@@3j)egO{RhQQTNy~4ezQ6%AM0T`@Yb@G7A(} z4tvFM!ZjLoQKC!{k2bB`3In7c%63 zGsqv*P?9{?Zbsd1k%Cz!+B*?CmuWbIewm~{TACpu*Q^ypzBROG1WOivOKtf#vZcLY z28prZE9t24XLYoi4YmA7Wg;1ixn{@Ql+t?Su?tD<(a4jYp$~jfR~7c{te9KmwI1ZP zo~TC-H)(WiEb4|7jcz1-A83?Im+jTJ({cDiHRkRPtPEh6Aiw)awLVsjPiS|vJRp^9 zof)DZ_|UIY(5YIXOS7(RNV6i4Aj+ejgTW^keqD>YhQi+^tM3wdwzPYcTRv4;=rH7D z-JhwzK2sTy0dXj)YKSt2h1?Uo7kL5qdT5*x8l`pIC~rBVjO51{u}9GNGs4J3{trq1 z!{iVM!f$IWV=Aj2+fCj*oYSQ1e;clU6j;kvjSU&^tAS^c*M6w3{1CB>R92*i#p5I# z`FuT8U~SxV-jI!O-z3y?`%L#M57f7vScyEl2 ziG8$2cz~ybIwRjn zE;(&#R`fd5(>LbA747>z3srWJOL9=shJ ztZPK9&Obaejc%pyt%Ql>MY}0;9Q~!)VlDG}mUNgU<@OMY)o$|F(;- z48!5~ZByEl6Hdf9T6{w?g#Q{DmCkEBqMYLaYiM^>Or}FKj*;WMA7!(!e2L&(`Yx*~ zrMyV;l{xp(Q5WrX@hNJA1lu(>21T`c;D9e@()H0r;P#k%PR!FqK5kgAOp@|{XG^+Q z-Ws$C5l5vD5i+{5G~_KHBQ|UKY$&t)B8?8aQBTXon%Z)a#zX}UthV5&p-&6;J;Nvo zbkEora&0=BucS)Ox8Y++UG@Wh-%9prSnYp@(qtd&f!t(3XNnnuFytzWU<30{c3EC7@y&WUcMlF zGQ8X{`M9ZhA2&QgeMbs?$)Ek)_GjpPCSxwQ2iZ|89p}2~AAbZKt1Lg2&FsC03~ZeW z^E*CQx9(;7W$?>v-D?Qj#%pZdo2>dX<4v~iEmr-h@fKV62CM$Wc!RBbg;jrSyu#MK z&Z<8$UMChkE+}#VDH8MlrxyMI^G6o=YVifvzqDnnxDN8Ir*22&>caol!vE25cDAn6 zs+E?jG*%sG*?|yI{YkY8+g%+3vBA09zf0Wx#9Z?3!DJ&8NJnuFX;pGvO7COxI->Vp z@m9khX+!J1bk+Sbe2a72{j#_LAL@OC<-`SX??ZxG>)nkb!c*ABkFfCLc%13x!yb4@?FNzZ-jC&v|vFo-a?N%_$JJfKJKiLm(Y*V{xdb$=OH9S zekP(g3rc6kEdl|VrGgAQH@wY7i$lh+!M5e@Ax#>yI'; + } + }); + return true; + } + form.data('submit', true); + return false; + }); + form.data('uploadify_init', true); + } + + function on_upload_success(file, data, response) { + delete form.data('pending_uploads')[this.id]; + if (file.targetpath) { + $('#'+this.id).data('path', file.targetpath); + } else { + $('#'+this.id).data('path', data); + } + if ($.isEmptyObject(form.data('pending_uploads')) && form.data('submit')) { + form.submit(); + } + } + + function on_select(file) { + if (!form.data('uploadify_init')) { //hack around + init_form() + } + form.data('pending_uploads')[this.id] = true; + + //determine the target path and update post data if our backend requires + var swfuploadify = window['uploadify_' + this.id]; + if (swfuploadify.settings.determineName) { + jQuery.ajax({ + type : 'POST', + async : false, + dataType: 'json', + url : swfuploadify.settings.determineName, + beforeSend : add_csrf, + data : {filename: file.name, + upload_to: upload_to}, + success : function(data) { + for (key in data) { + swfuploadify.addFileParam(file.id, key, data[key]); + } + file.targetpath = data['targetpath']; + } + }); + } else { + //swfuploadify.addFileParam(file.id, 'targetname', file.name); + } + } + + function on_upload_error(file,errorCode,errorMsg,errorString, queue) { + delete form.data('pending_uploads')[this.id]; + } + + function on_upload_cancel() { + delete form.data('pending_uploads')[this.id]; + } + + options['onUploadSuccess'] = on_upload_success; + options['onSelect'] = on_select; + //options['onUploadStart'] = on_upload_start; + options['onUploadError'] = on_upload_error; + options['onUploadCancel'] = on_upload_cancel; + options['onSWFReady'] = init_form; //this may not work + /* Uploadify Setup */ + options['auto'] = true; + options['multi'] = false; + options['removeCompleted'] = false; + options['uploadLimit'] = 1; + $this.uploadify(options); + } + }); + }); +} + + diff --git a/directupload/templates/admin/includes/fieldset.html b/directupload/templates/admin/includes/fieldset.html new file mode 100644 index 0000000..7a03f5c --- /dev/null +++ b/directupload/templates/admin/includes/fieldset.html @@ -0,0 +1,36 @@ +{% load uploadify_tags %} +
+ {% if fieldset.name %}

{{ fieldset.name }}

{% endif %} + {% if fieldset.description %} +
{{ fieldset.description|safe }}
+ {% endif %} + {% for line in fieldset %} +
+ {% if line.fields|length_is:'1' %}{{ line.errors }}{% endif %} + {% for field in line %} + + {% if not line.fields|length_is:'1' and not field.is_readonly %}{{ field.errors }}{% endif %} + {% if field.is_checkbox %} + {{ field.field }}{{ field.label_tag }} + {% else %} + {{ field.label_tag }} + {% if field.is_readonly %} +

{{ field.contents }}

+ {% else %} + {# begin custom uploadify snippet #} + {% if field.field|is_file_field:line.model_admin.model %} + {% render_uploadify_field field.field model=line.model_admin.model %} + {% else %} + {{ field.field }} + {% endif %} + {# end snippet #} + {% endif %} + {% endif %} + {% if field.field.help_text %} +

{{ field.field.help_text|safe }}

+ {% endif %} +
+ {% endfor %} +
+ {% endfor %} + diff --git a/directupload/templates/uploadify/templatetags/head.html b/directupload/templates/uploadify/templatetags/head.html new file mode 100644 index 0000000..9ba8545 --- /dev/null +++ b/directupload/templates/uploadify/templatetags/head.html @@ -0,0 +1,9 @@ + +{{media}} + diff --git a/directupload/templates/uploadify/templatetags/render_uploadify_widget.html b/directupload/templates/uploadify/templatetags/render_uploadify_widget.html new file mode 100644 index 0000000..5d2879c --- /dev/null +++ b/directupload/templates/uploadify/templatetags/render_uploadify_widget.html @@ -0,0 +1 @@ +{{field}} diff --git a/directupload/templatetags/__init__.py b/directupload/templatetags/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/directupload/templatetags/uploadify_tags.py b/directupload/templatetags/uploadify_tags.py new file mode 100644 index 0000000..ad066c6 --- /dev/null +++ b/directupload/templatetags/uploadify_tags.py @@ -0,0 +1,49 @@ +from django import template +from django.db import models + +import copy + +register = template.Library() + +from classytags.core import Options +from classytags.helpers import InclusionTag +from classytags.arguments import Argument, KeywordArgument + +from directupload.widgets import UploadifyClearableFileInput + +@register.inclusion_tag('uploadify/templatetags/head.html') +def uploadify_head(): + return { + 'media': UploadifyClearableFileInput().media, + } + +class RenderUploadifyField(InclusionTag): + name = 'render_uploadify_field' + template = 'uploadify/templatetags/render_uploadify_widget.html' + options = Options( + Argument('field', resolve=True), + KeywordArgument('model', resolve=True, required=False), + KeywordArgument('model_field', resolve=True, required=False), + ) + + def get_context(self, context, field, model, model_field): + model = model.get('model', None) + model_field = model_field.get('model_field', None) + if not model_field and model: + model_field = model._meta.get_field(field.name) + if not model_field: + pass + widget = UploadifyClearableFileInput(db_field=model_field) + field.field = copy.copy(field.field) #looks weird but field is actually a bound field + field.field.widget = widget + return {'widget': widget, 'field':field} + +register.tag(RenderUploadifyField) + +def is_file_field(field, model): + #field|is_file_field:line.model_admin.model + model_field = model._meta.get_field(field.name) + return isinstance(model_field, models.FileField) + +register.filter('is_file_field', is_file_field) + diff --git a/directupload/urls.py b/directupload/urls.py new file mode 100644 index 0000000..2051fb1 --- /dev/null +++ b/directupload/urls.py @@ -0,0 +1,8 @@ +from django.conf.urls.defaults import patterns, url + +urlpatterns = patterns('directupload.views', + url(r'^uploadify-options/$', 'uploadify_options_view', name='uploadify-options'), + url(r'^upload/$', 'upload_file', name='uploadify-upload-file'), + url(r'^exists/$', 'determine_name', name='uploadify-determine-name'), +) + diff --git a/directupload/views.py b/directupload/views.py new file mode 100644 index 0000000..2f7d509 --- /dev/null +++ b/directupload/views.py @@ -0,0 +1,44 @@ +from django.http import HttpResponse, HttpResponseBadRequest +from django.core.files.storage import default_storage +from django.views.decorators.csrf import csrf_exempt +from django.utils import simplejson as json + +from directupload.backends import get_uploadify_backend + +from urlparse import parse_qsl +import os + +def uploadify_options_view(request): + if not request.POST: + return HttpResponseBadRequest() + uploadify_options = {} + if 'upload_to' in request.POST: + uploadify_options['folder'] = request.POST['upload_to'] + backend = get_uploadify_backend() + data = backend(request=request, + uploadify_options=uploadify_options).get_options_json() + return HttpResponse(data) + +@csrf_exempt +def upload_file(request): + #this is handled by a different session then the user's browser, hence csrf exempt + if not request.POST: + return HttpResponseBadRequest() + from directupload.djangoview import unsign + data = dict(parse_qsl(unsign(request.POST['payload']))) + assert data['request_time'] #TODO respect some expiration + path = request.POST.get('targetpath', os.path.join(data['upload_to'], request.POST['Filename'])) + file_path = default_storage.save(path, request.FILES['Filedata']) #TODO how to tell the storage engine not to rename? + return HttpResponse(file_path) + +def determine_name(request): + if not request.POST: + return HttpResponseBadRequest() + desired_path = os.path.join(request.POST['upload_to'], request.POST['filename']) + path = default_storage.get_available_name(desired_path) + data = {'targetpath':path, + 'targetname':os.path.split(path)[-1],} + backend = get_uploadify_backend() + backend(request=request, uploadify_options={'folder':request.POST['upload_to']}).update_post_params(data) + return HttpResponse(json.dumps(data)) + diff --git a/directupload/widgets.py b/directupload/widgets.py new file mode 100644 index 0000000..78c4150 --- /dev/null +++ b/directupload/widgets.py @@ -0,0 +1,69 @@ +from django.forms.widgets import FileInput, ClearableFileInput +from django.core.files.storage import default_storage +from django.db.models.fields.files import FileField +from django.conf import settings + +class UploadifyInputMixin(object): + db_field = None + + class Media: #this does not work for the admin as django ignores it [WTF] + css = {'all': ('uploadify/uploadify.css',)} + if settings.DEBUG: + js = ('uploadify/jquery.uploadify.js', 'uploadify/widget.js') + else: + js = ('uploadify/jquery.uploadify.min.js', 'uploadify/widget.js') + + def get_file_field(self): + if self.db_field: + return self.db_field + return FileField(upload_to='', storage=default_storage) + + def value_from_datadict(self, data, files, name): + "File widgets take data from FILES, not POST" + if name in data: + file_path = data[name] + file_field = self.get_file_field() + file_obj = file_field.storage.open(file_path) + file_copy = file_field.attr_class(None, file_field, file_path) + file_copy.file = file_obj + file_copy._committed = True + return file_copy + return None + + def prepare_attrs(self, attrs): + attrs = attrs or {} + file_field = self.get_file_field() + attrs['class'] = 'uploadifyinput' + attrs['data-upload-to'] = file_field.upload_to + return attrs + +class UploadifyFileInput(UploadifyInputMixin, FileInput): + def __init__(self, *args, **kwargs): + self.db_field = kwargs.pop('db_field', None) + FileInput.__init__(self, *args, **kwargs) + + def value_from_datadict(self, data, files, name): + file_obj = UploadifyInputMixin.value_from_datadict(self, data, files, name) + if file_obj: + return file_obj + return super(UploadifyFileInput, self).value_from_datadict(data, files, name) + + def render(self, name, value, attrs=None): + attrs = self.prepare_attrs(attrs) + return super(UploadifyFileInput, self).render(name, value, attrs) + +class UploadifyClearableFileInput(UploadifyInputMixin, ClearableFileInput): + def __init__(self, *args, **kwargs): + self.db_field = kwargs.pop('db_field', None) + ClearableFileInput.__init__(self, *args, **kwargs) + + def value_from_datadict(self, data, files, name): + file_obj = UploadifyInputMixin.value_from_datadict(self, data, files, name) + if file_obj: + return file_obj + return super(UploadifyClearableFileInput, self).value_from_datadict(data, files, name) + + def render(self, name, value, attrs=None): + attrs = self.prepare_attrs(attrs) + return super(UploadifyClearableFileInput, self).render(name, value, attrs) + diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..819dd3b --- /dev/null +++ b/setup.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python + +try: + from setuptools import setup, find_packages +except ImportError: + from distutils.core import setup, find_packages + +version = '0.0.1' + +setup(name='django-directupload', + version=version, + description='A Django application that offers direct uploading of files from your forms using Uploadify.', + author='Jason Kraus', + author_email='jasonk@cukerinteractive.com', + url='https://github.com/cuker/django-directupload', + packages=find_packages(exclude=['test_environment']), + include_package_data = True, + classifiers=['Development Status :: 4 - Beta', + 'Environment :: Web Environment', + 'Framework :: Django', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: BSD License', + 'Operating System :: OS Independent', + 'Programming Language :: Python', + 'Topic :: Utilities'], + ) +