# HG changeset patch # User cavaliet # Date 1304067504 -7200 # Node ID 8a881c9593d01dee45dd5b59106521d32b996435 # Parent 784ebba76424a813016aed6a2ffd4eed83ab7814 Add swfupload for local upload to create content view, with progress bar and error management. Update language files. diff -r 784ebba76424 -r 8a881c9593d0 src/ldt/ldt/ldt_utils/middleware/__init__.py diff -r 784ebba76424 -r 8a881c9593d0 src/ldt/ldt/ldt_utils/middleware/swfupload.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ldt/ldt/ldt_utils/middleware/swfupload.py Fri Apr 29 10:58:24 2011 +0200 @@ -0,0 +1,17 @@ +"""This middleware takes the session identifier in a POST message and adds it to the cookies instead. + +This is necessary because SWFUpload won't send proper cookies back; instead, all the cookies are +added to the form that gets POST-ed back to us. +""" + +from django.conf import settings +from django.core.urlresolvers import reverse + +class SWFUploadMiddleware(object): + + def process_request(self, request): + if (request.method == 'POST') and (request.path == reverse('ldt.ldt_utils.views.upload')) and (settings.SESSION_COOKIE_NAME in request.POST): + request.COOKIES[settings.SESSION_COOKIE_NAME] = request.POST[settings.SESSION_COOKIE_NAME] + + if request.POST.has_key('csrfmiddlewaretoken'): + request.COOKIES['csrftoken'] = request.POST['csrfmiddlewaretoken'] \ No newline at end of file diff -r 784ebba76424 -r 8a881c9593d0 src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/create_content.html --- a/src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/create_content.html Thu Apr 21 18:07:59 2011 +0200 +++ b/src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/create_content.html Fri Apr 29 10:58:24 2011 +0200 @@ -7,8 +7,11 @@ {{ block.super }} - - + + + + + {{ content_form.media.js }} {% endblock %} @@ -17,48 +20,25 @@ {{ content_form.media.css }} + {% endblock %} {% block js_declaration %} {% endblock %} @@ -88,7 +68,7 @@
{% trans "Create content" %}
-
+
{% csrf_token %} @@ -114,11 +94,17 @@
{{ content_form.media_input_type.errors }}{{ content_form.media_input_type.label_tag }}{{content_form.media_input_type}}
-
{{ media_form.media_file.errors }}{{ media_form.media_file.label_tag }}{{media_form.media_file}}
+
+ {{ media_form.media_file.errors }} + {% comment %}{{ media_form.media_file.label_tag }}{{media_form.media_file}}{% endcomment %} +
+ +
+
+
{{ media_form.external_src_url.errors }}{{ media_form.external_src_url.label_tag }}{{ media_form.external_src_url }}
{{ media_form.src.errors }}{{ media_form.src.label_tag }}{{ media_form.src }}
-
@@ -132,7 +118,7 @@ {% if iri_id %}{% endif %}
- + {% endblock %} diff -r 784ebba76424 -r 8a881c9593d0 src/ldt/ldt/ldt_utils/urls.py --- a/src/ldt/ldt/ldt_utils/urls.py Thu Apr 21 18:07:59 2011 +0200 +++ b/src/ldt/ldt/ldt_utils/urls.py Fri Apr 29 10:58:24 2011 +0200 @@ -48,5 +48,6 @@ url(r'^space/ldt/save/$', 'views.save_ldtProject'), url(r'^space/ldt/publish/(?P[\w-]*)(?:/(?Ptrue|false))?$', 'views.publish'), url(r'^space/ldt/unpublish/(?P[\w-]*)(?:/(?Ptrue|false))?$', 'views.unpublish'), + url(r'^space/upload/$', 'views.upload'), ) diff -r 784ebba76424 -r 8a881c9593d0 src/ldt/ldt/ldt_utils/views.py --- a/src/ldt/ldt/ldt_utils/views.py Thu Apr 21 18:07:59 2011 +0200 +++ b/src/ldt/ldt/ldt_utils/views.py Fri Apr 29 10:58:24 2011 +0200 @@ -32,6 +32,9 @@ import os import urllib2 +from django.views.decorators.csrf import csrf_exempt + + @login_required def workspace(request): @@ -670,7 +673,7 @@ if cleaned_data['src'].startswith("rtmp://") or cleaned_data['src'].startswith("http://"): cleaned_data['videopath'] = '' media, created = Media.objects.get_or_create(src=cleaned_data['src'], defaults=cleaned_data) #@UndefinedVariable - elif media_input_type == "url" or media_input_type == "upload" : + elif media_input_type == "url" or media_input_type == "upload" : # copy file #complet src destination_file = None @@ -683,8 +686,9 @@ if not source_filename: source_filename = urlparse.urlparse(url).path.rstrip("/").split('/')[-1] elif media_input_type == "upload": - source_file = request.FILES['media-media_file'] - source_filename = source_file.name + #source_file = request.FILES['media-media_file'] + # At this point the file has already be uploaded thanks to the upload view, and original file name is sent through a post var + source_filename = request.POST["media-local_file_name"] source_filename = ldt_utils_path.sanitize_filename(source_filename) destination_filepath = os.path.join(settings.STREAM_PATH, source_filename) @@ -696,39 +700,56 @@ else: base_basename_filename = base_source_filename[:-1 * (len(extension) + 1)] i = 0 + init_path = destination_filepath + init_name = source_filename while os.path.exists(destination_filepath): base_source_filename = "%s.%d.%s" % (base_basename_filename, i, extension) destination_filepath = os.path.join(settings.STREAM_PATH, base_source_filename) i += 1 + + if media_input_type == "url": + # we upload the file if we are in url case + destination_file = open(destination_filepath, "wb") + chunck = source_file.read(2048) + while chunck: + destination_file.write(chunck) + chunck = source_file.read(2048) - destination_file = open(destination_filepath, "w") + elif media_input_type == "upload": + # Since the file names have been 1 iteration too far, we rebuild the existing file name + if i == 1 : + base_source_filename = init_name + destination_filepath = init_path + else : + i -= 2 + base_source_filename = "%s.%d.%s" % (base_basename_filename, i, extension) + destination_filepath = os.path.join(settings.STREAM_PATH, base_source_filename) + + src_prefix = settings.STREAM_SRC_PREFIX.rstrip("/") if len(src_prefix) > 0: cleaned_data["src"] = src_prefix + "/" + base_source_filename else: cleaned_data["src"] = base_source_filename - chunck = source_file.read(2048) - while chunck: - destination_file.write(chunck) - chunck = source_file.read(2048) - + except Exception as inst: logging.debug("write_content_base : POST error when processing file:" + str(inst)) #@UndefinedVariable form_status = "error" #set error for form if media_input_type == "url": errors = media_form._errors.setdefault("external_src_url", ErrorList()) - errors.append(_("Problem when downloading file from url : ") + str(inst)) + errors.append(_("Problem when downloading file from url : ") + url) elif media_input_type == "upload": errors = media_form._errors.setdefault("media_file", ErrorList()) errors.append(_("Problem when uploading file : ") + str(inst)) finally: - if destination_file: - destination_file.close() - if source_file: - source_file.close() - + if media_input_type == "url": + if destination_file: + destination_file.close() + if source_file: + source_file.close() + if form_status != "error": #try: del cleaned_data["media_file"] @@ -741,6 +762,7 @@ media, created = Media.objects.get_or_create(src=cleaned_data['src'], defaults=cleaned_data) #@UndefinedVariable else: media = None + if media and not created: for attribute in ('external_id', 'external_permalink', 'external_publication_url', 'external_src_url', 'media_creation_date', 'videopath', 'duration', 'description', 'title'): @@ -809,7 +831,10 @@ else: create_content_action = reverse('ldt.ldt_utils.views.write_content') - return render_to_response('ldt/ldt_utils/create_content.html', {'content_form': content_form, 'media_form': media_form, 'form_status': form_status, 'create_content_action': create_content_action, 'iri_id': iri_id}, context_instance=RequestContext(request)) + session_key = request.COOKIES[settings.SESSION_COOKIE_NAME] + cookie_name = settings.SESSION_COOKIE_NAME + + return render_to_response('ldt/ldt_utils/create_content.html', {'content_form': content_form, 'media_form': media_form, 'form_status': form_status, 'create_content_action': create_content_action, 'iri_id': iri_id, 'session_key':session_key, 'cookie_name':cookie_name}, context_instance=RequestContext(request)) @login_required def prepare_delete_content(request, iri_id=None): @@ -838,4 +863,40 @@ if iri_id: Content.objects.filter(iri_id=iri_id).delete() #@UndefinedVariable + + +def upload(request): + if request.method == 'POST': + for field_name in request.FILES: + # We get the file name + source_file = request.FILES[field_name] + source_filename = source_file.name + # We sanitize the file name : no space, only lower case. + source_filename = ldt_utils_path.sanitize_filename(source_filename) + destination_filepath = os.path.join(settings.STREAM_PATH, source_filename) + base_source_filename = source_filename + extension = base_source_filename.split(".")[-1] + if extension == base_source_filename: + extension = "" + base_basename_filename = base_source_filename + else: + base_basename_filename = base_source_filename[:-1 * (len(extension) + 1)] + i = 0 + # We search if there is already a file with the same name, and rename the target by name.X.ext + while os.path.exists(destination_filepath): + base_source_filename = "%s.%d.%s" % (base_basename_filename, i, extension) + destination_filepath = os.path.join(settings.STREAM_PATH, base_source_filename) + i += 1 + + destination_file = open(destination_filepath, "wb") + + for chunk in source_file.chunks(): + destination_file.write(chunk) + destination_file.close() + + + # indicate that everything is OK for SWFUpload + return HttpResponse("ok", mimetype="text/plain") + else: + return HttpResponse("notok", mimetype="text/plain") diff -r 784ebba76424 -r 8a881c9593d0 src/ldt/ldt/locale/en/LC_MESSAGES/django.mo Binary file src/ldt/ldt/locale/en/LC_MESSAGES/django.mo has changed diff -r 784ebba76424 -r 8a881c9593d0 src/ldt/ldt/locale/en/LC_MESSAGES/django.po --- a/src/ldt/ldt/locale/en/LC_MESSAGES/django.po Thu Apr 21 18:07:59 2011 +0200 +++ b/src/ldt/ldt/locale/en/LC_MESSAGES/django.po Fri Apr 29 10:58:24 2011 +0200 @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2011-03-03 15:12+0100\n" +"POT-Creation-Date: 2011-04-28 13:29+0200\n" "PO-Revision-Date: 2010-02-17 03:53+0100\n" "Last-Translator: Yves-Marie Haussonne \n" "Language-Team: LANGUAGE \n" @@ -24,31 +24,31 @@ msgid "Time" msgstr "Time" -#: .\ldt_utils\forms.py:43 .\ldt_utils\models.py:100 +#: .\ldt_utils\forms.py:38 .\ldt_utils\models.py:101 msgid "content.content_creation_date" msgstr "content creation date" -#: .\ldt_utils\forms.py:44 +#: .\ldt_utils\forms.py:39 msgid "content.media_input_type" msgstr "Media source type" -#: .\ldt_utils\forms.py:44 +#: .\ldt_utils\forms.py:39 msgid "file_upload" msgstr "file upload" -#: .\ldt_utils\forms.py:44 +#: .\ldt_utils\forms.py:39 msgid "url" msgstr "url" -#: .\ldt_utils\forms.py:44 +#: .\ldt_utils\forms.py:39 msgid "existing_media" msgstr "existing media" -#: .\ldt_utils\forms.py:44 +#: .\ldt_utils\forms.py:39 msgid "create_media" msgstr "create media" -#: .\ldt_utils\forms.py:44 +#: .\ldt_utils\forms.py:39 msgid "none_media" msgstr "no media" @@ -109,101 +109,101 @@ msgid "media.mimetype" msgstr "mimetype" -#: .\ldt_utils\models.py:92 +#: .\ldt_utils\models.py:93 msgid "content.iri_id" msgstr "iri id" -#: .\ldt_utils\models.py:93 +#: .\ldt_utils\models.py:94 msgid "content.iriurl" msgstr "iri url" -#: .\ldt_utils\models.py:94 +#: .\ldt_utils\models.py:95 msgid "content.creation_date" msgstr "content creation date" -#: .\ldt_utils\models.py:95 +#: .\ldt_utils\models.py:96 msgid "content.update_date" msgstr "content update date" -#: .\ldt_utils\models.py:96 +#: .\ldt_utils\models.py:97 msgid "content.title" msgstr "title" -#: .\ldt_utils\models.py:97 +#: .\ldt_utils\models.py:98 msgid "content.description" msgstr "description" -#: .\ldt_utils\models.py:98 +#: .\ldt_utils\models.py:99 msgid "content.authors" msgstr "authors" -#: .\ldt_utils\models.py:99 +#: .\ldt_utils\models.py:100 msgid "content.duration" msgstr "duration (ms)" -#: .\ldt_utils\models.py:288 +#: .\ldt_utils\models.py:289 msgid "created by" msgstr "created by" -#: .\ldt_utils\models.py:289 +#: .\ldt_utils\models.py:290 msgid "changed by" msgstr "changed by" -#: .\ldt_utils\views.py:81 .\ldt_utils\views.py:358 .\ldt_utils\views.py:404 +#: .\ldt_utils\views.py:76 .\ldt_utils\views.py:353 .\ldt_utils\views.py:399 msgid "You can not access this project" msgstr "You can not access this project" -#: .\ldt_utils\views.py:562 +#: .\ldt_utils\views.py:564 #, python-format msgid "the project %(title)s is published. please unpublish before deleting." msgstr "the project %(title)s is published. please unpublish before deleting." -#: .\ldt_utils\views.py:563 +#: .\ldt_utils\views.py:565 msgid "can not delete the project. Please correct the following error" msgstr "can not delete the project. Please correct the following error" -#: .\ldt_utils\views.py:564 +#: .\ldt_utils\views.py:566 msgid "title error deleting project" msgstr "Error when deleting project" -#: .\ldt_utils\views.py:566 +#: .\ldt_utils\views.py:568 #, python-format msgid "please confirm deleting project %(title)s" msgstr "Please confirm deleting project %(title)s" -#: .\ldt_utils\views.py:567 +#: .\ldt_utils\views.py:569 msgid "confirm deletion" msgstr "Confirm deletion" -#: .\ldt_utils\views.py:721 +#: .\ldt_utils\views.py:725 msgid "Problem when downloading file from url : " msgstr "Problem when downloading file from url: " -#: .\ldt_utils\views.py:724 +#: .\ldt_utils\views.py:728 .\ldt_utils\views.py:793 msgid "Problem when uploading file : " msgstr "Problem when uploading file: " -#: .\ldt_utils\views.py:792 +#: .\ldt_utils\views.py:863 #, python-format msgid "There is %(count)d error when deleting content" msgid_plural "There are %(count)d errors when deleting content" msgstr[0] "There is %(count)d error when deleting content" msgstr[1] "There are %(count)d errors when deleting content" -#: .\ldt_utils\views.py:793 +#: .\ldt_utils\views.py:864 msgid "title error deleting content" msgstr "Error when deleting content" -#: .\ldt_utils\views.py:795 +#: .\ldt_utils\views.py:866 #, python-format msgid "Confirm delete content %(titles)s" msgstr "Confirm delete content %(titles)s" -#: .\ldt_utils\views.py:796 +#: .\ldt_utils\views.py:867 msgid "confirm delete content" msgstr "Confirm delete content" -#: .\ldt_utils\views.py:827 +#: .\ldt_utils\views.py:901 #, python-format msgid "" "Content '%(title)s' is referenced by this project : %(project_titles)s. " @@ -270,7 +270,16 @@ msgid "Copy" msgstr "Copy" -#: .\ldt_utils\templates\ldt\ldt_utils\create_content.html.py:47 +#: .\ldt_utils\templates\ldt\ldt_utils\create_content.html.py:80 +msgid "Browse" +msgstr "" + +#: .\ldt_utils\templates\ldt\ldt_utils\create_content.html.py:123 +#, fuzzy +msgid "File uploaded" +msgstr "file upload" + +#: .\ldt_utils\templates\ldt\ldt_utils\create_content.html.py:198 msgid "" "The operation could not be performed because one or more error(s) occurred." "
Please resubmit the content form after making the following changes:" @@ -278,7 +287,7 @@ "The operation could not be performed because one or more error(s) occurred." "
Please resubmit the content form after making the following changes:" -#: .\ldt_utils\templates\ldt\ldt_utils\create_content.html.py:58 +#: .\ldt_utils\templates\ldt\ldt_utils\create_content.html.py:209 msgid "" "The operation could not be performed because one or more error(s) occurred." "
Please resubmit the media form after making the following changes:" @@ -286,26 +295,26 @@ "The operation could not be performed because one or more error(s) occurred." "
Please resubmit the media form after making the following changes:" -#: .\ldt_utils\templates\ldt\ldt_utils\create_content.html.py:68 +#: .\ldt_utils\templates\ldt\ldt_utils\create_content.html.py:219 #: .\ldt_utils\templates\ldt\ldt_utils\partial\contentslist.html.py:21 msgid "Create content" msgstr "Create content" -#: .\ldt_utils\templates\ldt\ldt_utils\create_content.html.py:105 +#: .\ldt_utils\templates\ldt\ldt_utils\create_content.html.py:263 msgid "media file is being processed please wait." msgstr "media file is being processed please wait." -#: .\ldt_utils\templates\ldt\ldt_utils\create_content.html.py:109 +#: .\ldt_utils\templates\ldt\ldt_utils\create_content.html.py:267 #: .\ldt_utils\templates\ldt\ldt_utils\create_ldt.html.py:59 #: .\ldt_utils\templates\ldt\ldt_utils\error_confirm.html.py:49 msgid "close_cancel" msgstr "Close" -#: .\ldt_utils\templates\ldt\ldt_utils\create_content.html.py:110 +#: .\ldt_utils\templates\ldt\ldt_utils\create_content.html.py:268 msgid "delete" msgstr "Approve delete" -#: .\ldt_utils\templates\ldt\ldt_utils\create_content.html.py:111 +#: .\ldt_utils\templates\ldt\ldt_utils\create_content.html.py:269 msgid "write" msgstr "write" @@ -339,31 +348,31 @@ msgid "create_project" msgstr "Create new project" -#: .\ldt_utils\templates\ldt\ldt_utils\embed_popup.html.py:60 +#: .\ldt_utils\templates\ldt\ldt_utils\embed_popup.html.py:63 msgid "project id" msgstr "project id" -#: .\ldt_utils\templates\ldt\ldt_utils\embed_popup.html.py:61 +#: .\ldt_utils\templates\ldt\ldt_utils\embed_popup.html.py:64 msgid "copy to clipboard" msgstr "copy to clipboard" -#: .\ldt_utils\templates\ldt\ldt_utils\embed_popup.html.py:70 +#: .\ldt_utils\templates\ldt\ldt_utils\embed_popup.html.py:73 msgid "popup_player" msgstr "player" -#: .\ldt_utils\templates\ldt\ldt_utils\embed_popup.html.py:70 +#: .\ldt_utils\templates\ldt\ldt_utils\embed_popup.html.py:73 msgid "popup_seo_body" msgstr "seo" -#: .\ldt_utils\templates\ldt\ldt_utils\embed_popup.html.py:70 +#: .\ldt_utils\templates\ldt\ldt_utils\embed_popup.html.py:73 msgid "popup_seo_meta" msgstr "meta" -#: .\ldt_utils\templates\ldt\ldt_utils\embed_popup.html.py:70 +#: .\ldt_utils\templates\ldt\ldt_utils\embed_popup.html.py:73 msgid "popup_links" msgstr "links" -#: .\ldt_utils\templates\ldt\ldt_utils\embed_popup.html.py:84 +#: .\ldt_utils\templates\ldt\ldt_utils\embed_popup.html.py:87 msgid "clik here to see the project content" msgstr "clik here to see the project content" @@ -383,24 +392,26 @@ msgid "do_delete" msgstr "Approve delete" -#: .\ldt_utils\templates\ldt\ldt_utils\init_ldt_full.html.py:17 +#: .\ldt_utils\templates\ldt\ldt_utils\init_ldt_full.html.py:16 msgid "" "Your current work is modified. Click Cancel and save it one last time before " "leaving. Click OK to leave without saving." -msgstr "Your current work is modified. Click Cancel and save it one last time before leaving. Click OK to leave without saving." +msgstr "" +"Your current work is modified. Click Cancel and save it one last time before " +"leaving. Click OK to leave without saving." #: .\ldt_utils\templates\ldt\ldt_utils\ldt_list.html.py:77 -#: .\ldt_utils\templates\ldt\ldt_utils\workspace_base.html.py:63 +#: .\ldt_utils\templates\ldt\ldt_utils\workspace_base.html.py:64 msgid "project list" msgstr "Projects" #: .\ldt_utils\templates\ldt\ldt_utils\ldt_list.html.py:79 -#: .\ldt_utils\templates\ldt\ldt_utils\workspace_base.html.py:54 -#: .\ldt_utils\templates\ldt\ldt_utils\workspace_base.html.py:65 +#: .\ldt_utils\templates\ldt\ldt_utils\workspace_base.html.py:55 +#: .\ldt_utils\templates\ldt\ldt_utils\workspace_base.html.py:66 msgid "search" msgstr "search" -#: .\ldt_utils\templates\ldt\ldt_utils\workspace_base.html.py:52 +#: .\ldt_utils\templates\ldt\ldt_utils\workspace_base.html.py:53 msgid "content list" msgstr "contents" @@ -408,28 +419,28 @@ msgid "preview media" msgstr "preview media" -#: .\ldt_utils\templates\ldt\ldt_utils\partial\projectslist.html.py:12 -#: .\ldt_utils\templates\ldt\ldt_utils\partial\projectslist.html.py:28 +#: .\ldt_utils\templates\ldt\ldt_utils\partial\projectslist.html.py:13 +#: .\ldt_utils\templates\ldt\ldt_utils\partial\projectslist.html.py:15 msgid "open ldt" msgstr "open ldt" -#: .\ldt_utils\templates\ldt\ldt_utils\partial\projectslist.html.py:13 +#: .\ldt_utils\templates\ldt\ldt_utils\partial\projectslist.html.py:17 msgid "copy project" msgstr "Copy your project" -#: .\ldt_utils\templates\ldt\ldt_utils\partial\projectslist.html.py:14 +#: .\ldt_utils\templates\ldt\ldt_utils\partial\projectslist.html.py:18 msgid "link json by id" msgstr "link json by id" -#: .\ldt_utils\templates\ldt\ldt_utils\partial\projectslist.html.py:17 +#: .\ldt_utils\templates\ldt\ldt_utils\partial\projectslist.html.py:21 msgid "Project published, click to unpublish" msgstr "Project published, click to unpublish" -#: .\ldt_utils\templates\ldt\ldt_utils\partial\projectslist.html.py:19 +#: .\ldt_utils\templates\ldt\ldt_utils\partial\projectslist.html.py:23 msgid "Project not published, click to publish" msgstr "Project not published, click to publish" -#: .\ldt_utils\templates\ldt\ldt_utils\partial\projectslist.html.py:37 +#: .\ldt_utils\templates\ldt\ldt_utils\partial\projectslist.html.py:40 msgid "Create project" msgstr "Create new project" @@ -693,47 +704,47 @@ msgid "page_title" msgstr "Ldt Platform" -#: .\text\models.py:22 +#: .\text\models.py:17 msgid "annotation.external_id" msgstr "external id" -#: .\text\models.py:23 +#: .\text\models.py:18 msgid "annotation.uri" msgstr "uri" -#: .\text\models.py:24 +#: .\text\models.py:19 msgid "annotation.tags" msgstr "tags" -#: .\text\models.py:25 +#: .\text\models.py:20 msgid "annotation.title" msgstr "title" -#: .\text\models.py:26 +#: .\text\models.py:21 msgid "annotation.description" msgstr "description" -#: .\text\models.py:27 +#: .\text\models.py:22 msgid "annotation.text" msgstr "text" -#: .\text\models.py:28 +#: .\text\models.py:23 msgid "annotation.color" msgstr "color" -#: .\text\models.py:29 +#: .\text\models.py:24 msgid "creator.title" msgstr "title" -#: .\text\models.py:30 +#: .\text\models.py:25 msgid "contributor.title" msgstr "title" -#: .\text\models.py:31 +#: .\text\models.py:26 msgid "annotation.creation_date" msgstr "creation date" -#: .\text\models.py:32 +#: .\text\models.py:27 msgid "annotation.update_date" msgstr "update date" @@ -769,7 +780,7 @@ msgid "The two emails didn't match." msgstr "The two emails didn't match." -#: .\user\views.py:45 .\user\templates\registration\login.html.py:24 +#: .\user\views.py:44 .\user\templates\registration\login.html.py:24 msgid "Sorry, that's not a valid username or password." msgstr "Sorry, that's not a valid username or password." diff -r 784ebba76424 -r 8a881c9593d0 src/ldt/ldt/locale/fr/LC_MESSAGES/django.mo Binary file src/ldt/ldt/locale/fr/LC_MESSAGES/django.mo has changed diff -r 784ebba76424 -r 8a881c9593d0 src/ldt/ldt/locale/fr/LC_MESSAGES/django.po --- a/src/ldt/ldt/locale/fr/LC_MESSAGES/django.po Thu Apr 21 18:07:59 2011 +0200 +++ b/src/ldt/ldt/locale/fr/LC_MESSAGES/django.po Fri Apr 29 10:58:24 2011 +0200 @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2011-03-03 15:12+0100\n" +"POT-Creation-Date: 2011-04-28 13:24+0200\n" "PO-Revision-Date: 2010-03-09 15:52+0100\n" "Last-Translator: Yves-Marie Haussonne \n" "Language-Team: LANGUAGE \n" @@ -24,31 +24,31 @@ msgid "Time" msgstr "Time" -#: .\ldt_utils\forms.py:43 .\ldt_utils\models.py:100 +#: .\ldt_utils\forms.py:38 .\ldt_utils\models.py:101 msgid "content.content_creation_date" msgstr "Date de creation du contenu" -#: .\ldt_utils\forms.py:44 +#: .\ldt_utils\forms.py:39 msgid "content.media_input_type" msgstr "Source du média" -#: .\ldt_utils\forms.py:44 +#: .\ldt_utils\forms.py:39 msgid "file_upload" msgstr "upload fichier" -#: .\ldt_utils\forms.py:44 +#: .\ldt_utils\forms.py:39 msgid "url" msgstr "url" -#: .\ldt_utils\forms.py:44 +#: .\ldt_utils\forms.py:39 msgid "existing_media" msgstr "média existant" -#: .\ldt_utils\forms.py:44 +#: .\ldt_utils\forms.py:39 msgid "create_media" msgstr "source externe : fichier streamé, statique, url youtube..." -#: .\ldt_utils\forms.py:44 +#: .\ldt_utils\forms.py:39 msgid "none_media" msgstr "Aucun" @@ -109,101 +109,102 @@ msgid "media.mimetype" msgstr "mimetype" -#: .\ldt_utils\models.py:92 +#: .\ldt_utils\models.py:93 msgid "content.iri_id" msgstr "iri id" -#: .\ldt_utils\models.py:93 +#: .\ldt_utils\models.py:94 msgid "content.iriurl" msgstr "iri url" -#: .\ldt_utils\models.py:94 +#: .\ldt_utils\models.py:95 msgid "content.creation_date" msgstr "date de création" -#: .\ldt_utils\models.py:95 +#: .\ldt_utils\models.py:96 msgid "content.update_date" msgstr "Date de maj" -#: .\ldt_utils\models.py:96 +#: .\ldt_utils\models.py:97 msgid "content.title" msgstr "titre" -#: .\ldt_utils\models.py:97 +#: .\ldt_utils\models.py:98 msgid "content.description" msgstr "Description" -#: .\ldt_utils\models.py:98 +#: .\ldt_utils\models.py:99 msgid "content.authors" msgstr "Autheurs" -#: .\ldt_utils\models.py:99 +#: .\ldt_utils\models.py:100 msgid "content.duration" msgstr "Durée (ms)" -#: .\ldt_utils\models.py:288 +#: .\ldt_utils\models.py:289 msgid "created by" msgstr "créé par" -#: .\ldt_utils\models.py:289 +#: .\ldt_utils\models.py:290 msgid "changed by" msgstr "modifié par" -#: .\ldt_utils\views.py:81 .\ldt_utils\views.py:358 .\ldt_utils\views.py:404 +#: .\ldt_utils\views.py:76 .\ldt_utils\views.py:353 .\ldt_utils\views.py:399 msgid "You can not access this project" msgstr "vous n'avez pas l'autorisation d'accéder à ce projet" -#: .\ldt_utils\views.py:562 +#: .\ldt_utils\views.py:564 #, python-format msgid "the project %(title)s is published. please unpublish before deleting." msgstr "Le projet %(title)s est publié. Déplublier le avant de l'effacer." -#: .\ldt_utils\views.py:563 +#: .\ldt_utils\views.py:565 msgid "can not delete the project. Please correct the following error" -msgstr "Le projet ne peut pas être effacé. Veuillez corriger les erreurs suivantes." +msgstr "" +"Le projet ne peut pas être effacé. Veuillez corriger les erreurs suivantes." -#: .\ldt_utils\views.py:564 +#: .\ldt_utils\views.py:566 msgid "title error deleting project" msgstr "Erreur lors de l'effacement du projet" -#: .\ldt_utils\views.py:566 +#: .\ldt_utils\views.py:568 #, python-format msgid "please confirm deleting project %(title)s" -msgstr "Confirmer l'efaccement du projet intitulé %(title)s" +msgstr "Confirmer l'effacement du projet intitulé %(title)s" -#: .\ldt_utils\views.py:567 +#: .\ldt_utils\views.py:569 msgid "confirm deletion" msgstr "Confirmation d'effacement" -#: .\ldt_utils\views.py:721 +#: .\ldt_utils\views.py:725 msgid "Problem when downloading file from url : " msgstr "Problème lors du téléchargement du fichier : " -#: .\ldt_utils\views.py:724 +#: .\ldt_utils\views.py:728 .\ldt_utils\views.py:793 msgid "Problem when uploading file : " msgstr "Problème lors de l'upload du fichier : " -#: .\ldt_utils\views.py:792 +#: .\ldt_utils\views.py:863 #, python-format msgid "There is %(count)d error when deleting content" msgid_plural "There are %(count)d errors when deleting content" msgstr[0] "Il y a %(count)d erreur lors de l'effacement du contenu" msgstr[1] "Il y a %(count)d erreurs lors de l'effacement du contenu" -#: .\ldt_utils\views.py:793 +#: .\ldt_utils\views.py:864 msgid "title error deleting content" msgstr "Erreur lors de l'effacement du contenu" -#: .\ldt_utils\views.py:795 +#: .\ldt_utils\views.py:866 #, python-format msgid "Confirm delete content %(titles)s" msgstr "Veuillez confirmer l'effacement du contenu %(titles)s" -#: .\ldt_utils\views.py:796 +#: .\ldt_utils\views.py:867 msgid "confirm delete content" msgstr "Confirmation effacement contenu" -#: .\ldt_utils\views.py:827 +#: .\ldt_utils\views.py:901 #, python-format msgid "" "Content '%(title)s' is referenced by this project : %(project_titles)s. " @@ -270,40 +271,50 @@ msgid "Copy" msgstr "Copier" -#: .\ldt_utils\templates\ldt\ldt_utils\create_content.html.py:47 +#: .\ldt_utils\templates\ldt\ldt_utils\create_content.html.py:80 +msgid "Browse" +msgstr "Parcourir" + +#: .\ldt_utils\templates\ldt\ldt_utils\create_content.html.py:123 +msgid "File uploaded" +msgstr "Fichier téléversé" + +#: .\ldt_utils\templates\ldt\ldt_utils\create_content.html.py:198 msgid "" "The operation could not be performed because one or more error(s) occurred." "
Please resubmit the content form after making the following changes:" -msgstr "Opération impossible à cause d'une ou plusieurs erreurs.
Veuillez " +msgstr "" +"Opération impossible à cause d'une ou plusieurs erreurs.
Veuillez " "resoumettre le formulaire contenu après avoir fait les changements suivants:" -#: .\ldt_utils\templates\ldt\ldt_utils\create_content.html.py:58 +#: .\ldt_utils\templates\ldt\ldt_utils\create_content.html.py:209 msgid "" "The operation could not be performed because one or more error(s) occurred." "
Please resubmit the media form after making the following changes:" -msgstr "opération impossible à cause d'une ou plusieurs erreurs.
Veuillez " +msgstr "" +"opération impossible à cause d'une ou plusieurs erreurs.
Veuillez " "resoumettre le formulaire media après avoir fait les changements suivants:" -#: .\ldt_utils\templates\ldt\ldt_utils\create_content.html.py:68 +#: .\ldt_utils\templates\ldt\ldt_utils\create_content.html.py:219 #: .\ldt_utils\templates\ldt\ldt_utils\partial\contentslist.html.py:21 msgid "Create content" msgstr "Créer un contenu" -#: .\ldt_utils\templates\ldt\ldt_utils\create_content.html.py:105 +#: .\ldt_utils\templates\ldt\ldt_utils\create_content.html.py:263 msgid "media file is being processed please wait." -msgstr "Le fichier média est en cours de traitement. Veullez patienter." +msgstr "Le fichier média est en cours de traitement. Veuillez patienter." -#: .\ldt_utils\templates\ldt\ldt_utils\create_content.html.py:109 +#: .\ldt_utils\templates\ldt\ldt_utils\create_content.html.py:267 #: .\ldt_utils\templates\ldt\ldt_utils\create_ldt.html.py:59 #: .\ldt_utils\templates\ldt\ldt_utils\error_confirm.html.py:49 msgid "close_cancel" msgstr "Fermer" -#: .\ldt_utils\templates\ldt\ldt_utils\create_content.html.py:110 +#: .\ldt_utils\templates\ldt\ldt_utils\create_content.html.py:268 msgid "delete" msgstr "Effacer" -#: .\ldt_utils\templates\ldt\ldt_utils\create_content.html.py:111 +#: .\ldt_utils\templates\ldt\ldt_utils\create_content.html.py:269 msgid "write" msgstr "Enregistrer" @@ -337,31 +348,31 @@ msgid "create_project" msgstr "Créer un nouveau projet Ligne de Temps" -#: .\ldt_utils\templates\ldt\ldt_utils\embed_popup.html.py:60 +#: .\ldt_utils\templates\ldt\ldt_utils\embed_popup.html.py:63 msgid "project id" msgstr "Identifiant du projet " -#: .\ldt_utils\templates\ldt\ldt_utils\embed_popup.html.py:61 +#: .\ldt_utils\templates\ldt\ldt_utils\embed_popup.html.py:64 msgid "copy to clipboard" msgstr "Copier l'id dans le presse-papiers" -#: .\ldt_utils\templates\ldt\ldt_utils\embed_popup.html.py:70 +#: .\ldt_utils\templates\ldt\ldt_utils\embed_popup.html.py:73 msgid "popup_player" msgstr "Code Lecteur métadata" -#: .\ldt_utils\templates\ldt\ldt_utils\embed_popup.html.py:70 +#: .\ldt_utils\templates\ldt\ldt_utils\embed_popup.html.py:73 msgid "popup_seo_body" msgstr "Code SEO" -#: .\ldt_utils\templates\ldt\ldt_utils\embed_popup.html.py:70 +#: .\ldt_utils\templates\ldt\ldt_utils\embed_popup.html.py:73 msgid "popup_seo_meta" msgstr "Code balise meta en-tête" -#: .\ldt_utils\templates\ldt\ldt_utils\embed_popup.html.py:70 +#: .\ldt_utils\templates\ldt\ldt_utils\embed_popup.html.py:73 msgid "popup_links" msgstr "Liste de liens" -#: .\ldt_utils\templates\ldt\ldt_utils\embed_popup.html.py:84 +#: .\ldt_utils\templates\ldt\ldt_utils\embed_popup.html.py:87 msgid "clik here to see the project content" msgstr "cliquer ici pour voir le contenu du projet" @@ -381,24 +392,26 @@ msgid "do_delete" msgstr "Effacer" -#: .\ldt_utils\templates\ldt\ldt_utils\init_ldt_full.html.py:17 +#: .\ldt_utils\templates\ldt\ldt_utils\init_ldt_full.html.py:16 msgid "" "Your current work is modified. Click Cancel and save it one last time before " "leaving. Click OK to leave without saving." -msgstr "Vous avez un travail en cours. Cliquez sur Annuler et sauvegardez votre travail une dernière fois. Cliquez sur OK pour quitter sans sauvegarder." +msgstr "" +"Vous avez un travail en cours. Cliquez sur Annuler et sauvegardez votre " +"travail une dernière fois. Cliquez sur OK pour quitter sans sauvegarder." #: .\ldt_utils\templates\ldt\ldt_utils\ldt_list.html.py:77 -#: .\ldt_utils\templates\ldt\ldt_utils\workspace_base.html.py:63 +#: .\ldt_utils\templates\ldt\ldt_utils\workspace_base.html.py:64 msgid "project list" msgstr "Liste des projets" #: .\ldt_utils\templates\ldt\ldt_utils\ldt_list.html.py:79 -#: .\ldt_utils\templates\ldt\ldt_utils\workspace_base.html.py:54 -#: .\ldt_utils\templates\ldt\ldt_utils\workspace_base.html.py:65 +#: .\ldt_utils\templates\ldt\ldt_utils\workspace_base.html.py:55 +#: .\ldt_utils\templates\ldt\ldt_utils\workspace_base.html.py:66 msgid "search" msgstr "Recherche" -#: .\ldt_utils\templates\ldt\ldt_utils\workspace_base.html.py:52 +#: .\ldt_utils\templates\ldt\ldt_utils\workspace_base.html.py:53 msgid "content list" msgstr "Liste des contenus" @@ -406,28 +419,28 @@ msgid "preview media" msgstr "aperçu" -#: .\ldt_utils\templates\ldt\ldt_utils\partial\projectslist.html.py:12 -#: .\ldt_utils\templates\ldt\ldt_utils\partial\projectslist.html.py:28 +#: .\ldt_utils\templates\ldt\ldt_utils\partial\projectslist.html.py:13 +#: .\ldt_utils\templates\ldt\ldt_utils\partial\projectslist.html.py:15 msgid "open ldt" msgstr "Ouvrir sous Lignes de Temps" -#: .\ldt_utils\templates\ldt\ldt_utils\partial\projectslist.html.py:13 +#: .\ldt_utils\templates\ldt\ldt_utils\partial\projectslist.html.py:17 msgid "copy project" msgstr "Copier votre projet" -#: .\ldt_utils\templates\ldt\ldt_utils\partial\projectslist.html.py:14 +#: .\ldt_utils\templates\ldt\ldt_utils\partial\projectslist.html.py:18 msgid "link json by id" msgstr "Ouvrir le lecteur de métadata" -#: .\ldt_utils\templates\ldt\ldt_utils\partial\projectslist.html.py:17 +#: .\ldt_utils\templates\ldt\ldt_utils\partial\projectslist.html.py:21 msgid "Project published, click to unpublish" msgstr "Projet publié, cliquer pour de-publier" -#: .\ldt_utils\templates\ldt\ldt_utils\partial\projectslist.html.py:19 +#: .\ldt_utils\templates\ldt\ldt_utils\partial\projectslist.html.py:23 msgid "Project not published, click to publish" msgstr "Projet non publié, cliquer pour publier" -#: .\ldt_utils\templates\ldt\ldt_utils\partial\projectslist.html.py:37 +#: .\ldt_utils\templates\ldt\ldt_utils\partial\projectslist.html.py:40 msgid "Create project" msgstr "Créer un nouveau projet d'indexation" @@ -502,7 +515,8 @@ msgid "" "This page must be moderated at level %(moderation_level)s, post a message " "for moderator." -msgstr "Le niveau nécessaire pour modérer cette page est le niveau %" +msgstr "" +"Le niveau nécessaire pour modérer cette page est le niveau %" "(moderation_level)s, laisser un message pour le modérateur" #: .\templates\admin\cms_change_form.html.py:144 @@ -690,47 +704,47 @@ msgid "page_title" msgstr "Plateforme Ldt" -#: .\text\models.py:22 +#: .\text\models.py:17 msgid "annotation.external_id" msgstr "id externe" -#: .\text\models.py:23 +#: .\text\models.py:18 msgid "annotation.uri" msgstr "uri" -#: .\text\models.py:24 +#: .\text\models.py:19 msgid "annotation.tags" msgstr "tags" -#: .\text\models.py:25 +#: .\text\models.py:20 msgid "annotation.title" msgstr "titre" -#: .\text\models.py:26 +#: .\text\models.py:21 msgid "annotation.description" msgstr "Description" -#: .\text\models.py:27 +#: .\text\models.py:22 msgid "annotation.text" msgstr "texte d'annotation" -#: .\text\models.py:28 +#: .\text\models.py:23 msgid "annotation.color" msgstr "couleur d'annotation" -#: .\text\models.py:29 +#: .\text\models.py:24 msgid "creator.title" msgstr "titre" -#: .\text\models.py:30 +#: .\text\models.py:25 msgid "contributor.title" msgstr "titre" -#: .\text\models.py:31 +#: .\text\models.py:26 msgid "annotation.creation_date" msgstr "date de création" -#: .\text\models.py:32 +#: .\text\models.py:27 msgid "annotation.update_date" msgstr "Date de maj" @@ -766,7 +780,7 @@ msgid "The two emails didn't match." msgstr "les deux emails ne correspondent pas" -#: .\user\views.py:45 .\user\templates\registration\login.html.py:24 +#: .\user\views.py:44 .\user\templates\registration\login.html.py:24 msgid "Sorry, that's not a valid username or password." msgstr "Saisissez un nom d'utilisateur et un mot de passe valide." @@ -779,7 +793,8 @@ msgid "" "Please enter your new e-mail twice so we can verify you typed it in " "correctly." -msgstr "Saisissez deux fois votre nouvelle adresse émail afin de vérifier qu'il est " +msgstr "" +"Saisissez deux fois votre nouvelle adresse émail afin de vérifier qu'il est " "correctment" #: .\user\templates\ldt\user\change_email.html.py:32 @@ -913,7 +928,8 @@ msgid "" "Please enter your old password, for security's sake, and then enter your new " "password twice so we can verify you typed it in correctly." -msgstr "Par sécurité, veuillez enter votre ancien mot de passe puis le nouveau a " +msgstr "" +"Par sécurité, veuillez enter votre ancien mot de passe puis le nouveau a " "deux reprise afin de savoir si vous l'avez taper correctement " #: .\user\templates\registration\password_change_form.html.py:26 @@ -957,7 +973,8 @@ msgid "" "Please enter your new password twice so we can verify you typed it in " "correctly." -msgstr "veuillez enter votre nouveau mot de pass deux fois afin de le vérifier." +msgstr "" +"veuillez enter votre nouveau mot de pass deux fois afin de le vérifier." #: .\user\templates\registration\password_reset_confirm.html.py:27 msgid "Password reset unsuccessful" @@ -967,7 +984,8 @@ msgid "" "The password reset link was invalid, possibly because it has already been " "used. Please request a new password reset." -msgstr "Le lien de réinitialisation du mot de passe n'est pas valide, certainement " +msgstr "" +"Le lien de réinitialisation du mot de passe n'est pas valide, certainement " "car il a déjà été utilisé. veuiller demander une nouvelle réinitialisation." #: .\user\templates\registration\password_reset_done.html.py:8 @@ -978,13 +996,16 @@ msgid "" "We've e-mailed you instructions for setting your password to the e-mail " "address you submitted. You should be receiving it shortly." -msgstr "Nous vous avons envoyer les instructions de reinitialisation de votre mot de " +msgstr "" +"Nous vous avons envoyer les instructions de reinitialisation de votre mot de " "passe à l'adresse email que vous nous avez fournie. vous devriez les " "recevoir bientôt." #: .\user\templates\registration\password_reset_email.html.py:2 msgid "You're receiving this e-mail because you requested a password reset" -msgstr "Vous recevez ce mail car vous avez damender la réinitialisation du mot de passe" +msgstr "" +"Vous recevez ce mail car vous avez damender la réinitialisation du mot de " +"passe" #: .\user\templates\registration\password_reset_email.html.py:3 #, python-format @@ -993,7 +1014,8 @@ #: .\user\templates\registration\password_reset_email.html.py:5 msgid "Please go to the following page and choose a new password:" -msgstr "veuillez aller à la page suivante et choisissez un nouveau mot de passe :" +msgstr "" +"veuillez aller à la page suivante et choisissez un nouveau mot de passe :" #: .\user\templates\registration\password_reset_email.html.py:9 msgid "Your username, in case you've forgotten:" @@ -1012,7 +1034,8 @@ msgid "" "Forgotten your password? Enter your e-mail address below, and we'll e-mail " "instructions for setting a new one." -msgstr "Mot de passe oublié ? Entrez votre adresse email ci-dessous pour recevoir " +msgstr "" +"Mot de passe oublié ? Entrez votre adresse email ci-dessous pour recevoir " "les instructions pour en entrer un nouveau." #: .\user\templates\registration\password_reset_form.html.py:27 @@ -1032,7 +1055,9 @@ msgid "" "Vous avez bien activé votre compte, vous pouvez accedez à votre espace " "personnel." -msgstr "Vous avez bien activé votre compte, vous pouvez accedez à votre espace personnel." +msgstr "" +"Vous avez bien activé votre compte, vous pouvez accedez à votre espace " +"personnel." #: .\user\templates\registration\registration_active.html.py:10 msgid "retourner à la page de connexion" @@ -1047,7 +1072,8 @@ msgid "" "We've e-mailed you instructions for activate your account to the e-mail " "address you submitted. You should be receiving it shortly." -msgstr "Nous vous avons envoyé par courriel les instructions pour activer le compte " +msgstr "" +"Nous vous avons envoyé par courriel les instructions pour activer le compte " "à l'adresse que vous avez indiquée. Vous devriez le recevoir rapidement." #~ msgid "Create" diff -r 784ebba76424 -r 8a881c9593d0 src/ldt/ldt/media/js/projectscontents.js --- a/src/ldt/ldt/media/js/projectscontents.js Thu Apr 21 18:07:59 2011 +0200 +++ b/src/ldt/ldt/media/js/projectscontents.js Fri Apr 29 10:58:24 2011 +0200 @@ -399,3 +399,180 @@ }); } + +// +// Functions used in the create content view. +// +function onCreateContentReady(url_upload, media_prefix, post_added_params, btn_label, success_label) { + + var upload_from_local_done = false; + + $("#close_button").click(function (e) { + e.preventDefault(); + parent.$.nmTop().close(); + }); + $("#submit_button_write").click(function(e) { + $(".submitcontent-loader-content").show(); + }); + $(".media_fields").hide(); + $("#media_field_"+$("#id_content-media_input_type").val()).show(); + $("#id_content-media_input_type").change(function(e) { + $(".media_fields").hide(); + $("#media_field_"+$(e.target).val()).show(); + }); + // The textinput's id for external url is id_media-src + $('#id_media-src').bind('textchange', function(e) { testUrlValue(e); }); + + // We disable the default submit + $('#my_form').submit(function() { + if($('#id_content-media_input_type').val()=="upload" && upload_from_local_done==false){ + //alert("1. " + $('#id_content-media_input_type').val() + ", upload_done = " + upload_from_local_done); + startLocalUpload(); + return false; + } + else{ + //alert("2. " + $('#id_content-media_input_type').val()); + return true; + } + }); + + $("#upload_progress_bar").css({ width:"90%", height:"10" }); + + $('#media_fields_div').height(80); + + // We init the swfupload object + swfupload = new SWFUpload({ + debug: false, + + upload_url: url_upload, + flash_url: media_prefix+"swf/swfupload.swf", + + post_params: post_added_params, + + button_placeholder_id: "upload_btn", + button_width: "60", + button_height: "16", + button_cursor: SWFUpload.CURSOR.HAND, + button_text : '' + btn_label + '', + button_text_style : ".btnText { font-size: 12; font-family: Arial; }", + + file_types : "*.flv;*.f4v;*.mp4;*.mov;*.mp3", + file_types_description : "Media Files (flv, f4v, mov H264, mp4, mp3)", + file_upload_limit : "1", + file_queue_limit : "1", + + upload_progress_handler : uploadProgress, + upload_error_handler : uploadError, + //upload_success_handler : uploadSuccess, + upload_success_handler : function() { + try { + if($('#upload_progress_info').children().size()>0){ + $('#progress_info').remove(); + } + $('#upload_progress_info').append('

' + success_label + '.

'); + upload_from_local_done = true; + // Now that the file is uploaded, we submit the form + $('#my_form').submit(); + } + catch (ex) { + //this.debug(ex); + } + }, + + file_queued_handler : displayUploadPath, + //file_dialog_complete_handler: function() { this.startUpload(); }, + //upload_complete_handler: function() { this.startUpload(); }, + }); +} +function displayUploadPath(file) { + try { + $('#id_media-local_file_name').val(file.name); + } + catch (ex) { + //this.debug(ex); + } +} +function startLocalUpload(){ + swfupload.startUpload(); +} +function uploadProgress(file, bytesLoaded, bytesTotal) { + try { + var percent = Math.ceil((bytesLoaded / bytesTotal) * 100); + $("#upload_progress_bar").progressbar({ value: percent }); + } + catch (ex) { + //this.debug(ex); + } +} +function uploadSuccess(success_label) { + try { + if($('#upload_progress_info').children().size()>0){ + $('#progress_info').remove(); + } + $('#upload_progress_info').append('

' + success_label + '.

'); + upload_from_local_done = true; + // Now that the file is uploaded, we submit the form + $('#my_form').submit(); + } + catch (ex) { + //this.debug(ex); + } +} +function uploadError(file, errorCode, message) { + try { + if($('#upload_progress_info').children().size()>0){ + $('#progress_info').remove(); + } + switch (errorCode) { + case SWFUpload.UPLOAD_ERROR.HTTP_ERROR: + $('#upload_progress_info').append('

' + "Error Code: HTTP Error, File name: " + file.name + ", Message: " + message + '

'); + break; + case SWFUpload.UPLOAD_ERROR.UPLOAD_FAILED: + $('#upload_progress_info').append('

' + "Error Code: Upload Failed, File name: " + file.name + ", File size: " + file.size + ", Message: " + message + '

'); + break; + case SWFUpload.UPLOAD_ERROR.IO_ERROR: + $('#upload_progress_info').append('

' + "Error Code: IO Error, File name: " + file.name + ", Message: " + message + '

'); + break; + case SWFUpload.UPLOAD_ERROR.SECURITY_ERROR: + $('#upload_progress_info').append('

' + "Error Code: Security Error, File name: " + file.name + ", Message: " + message + '

'); + break; + case SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED: + $('#upload_progress_info').append('

' + "Error Code: Upload Limit Exceeded, File name: " + file.name + ", File size: " + file.size + ", Message: " + message + '

'); + break; + case SWFUpload.UPLOAD_ERROR.FILE_VALIDATION_FAILED: + $('#upload_progress_info').append('

' + "Error Code: File Validation Failed, File name: " + file.name + ", File size: " + file.size + ", Message: " + message + '

'); + break; + case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED: + $('#upload_progress_info').append('

' + "Error Code: FILE_CANCELLED" + '

'); + break; + case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED: + $('#upload_progress_info').append('

' + "STOPPED" + '

'); + break; + default: + $('#upload_progress_info').append('

' + "unhandled error: File name: " + file.name + ", File size: " + file.size + ", Message: " + message + '

'); + break; + } + } catch (ex) { + //this.debug(ex); + } +} + +// Test the value of the URL from the form to load a picture in case it is a youtube video +function testUrlValue(e){ + // First, we remove the current thumbnail if there is one. + if($('#media_field_create').children().size()>2){ + $('#external_thumbnail').remove(); + $('#media_fields_div').height(80); + } + // If the pasted text is a youtube url, we get the default thumbnail of the video and display it. + url = $('#id_media-src').val(); + if(url.match("youtube") && url.match("[\\?&]v=([^&#]*)")){ + results = url.match("[\\?&]v=([^&#]*)"); + vid = ( results === null ) ? url : results[1].substring(0,11); + if(vid.length===11){ + //$('#id_content-description').val($('#media_field_create') + 'Youtube Thumbnail'); + $('#media_field_create').append('Youtube Thumbnail'); + $('#media_fields_div').height(150); + } + } +} diff -r 784ebba76424 -r 8a881c9593d0 src/ldt/ldt/media/js/swfupload/swfupload.cookies.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ldt/ldt/media/js/swfupload/swfupload.cookies.js Fri Apr 29 10:58:24 2011 +0200 @@ -0,0 +1,53 @@ +/* + Cookie Plug-in + + This plug in automatically gets all the cookies for this site and adds them to the post_params. + Cookies are loaded only on initialization. The refreshCookies function can be called to update the post_params. + The cookies will override any other post params with the same name. +*/ + +var SWFUpload; +if (typeof(SWFUpload) === "function") { + SWFUpload.prototype.initSettings = function (oldInitSettings) { + return function () { + if (typeof(oldInitSettings) === "function") { + oldInitSettings.call(this); + } + + this.refreshCookies(false); // The false parameter must be sent since SWFUpload has not initialzed at this point + }; + }(SWFUpload.prototype.initSettings); + + // refreshes the post_params and updates SWFUpload. The sendToFlash parameters is optional and defaults to True + SWFUpload.prototype.refreshCookies = function (sendToFlash) { + if (sendToFlash === undefined) { + sendToFlash = true; + } + sendToFlash = !!sendToFlash; + + // Get the post_params object + var postParams = this.settings.post_params; + + // Get the cookies + var i, cookieArray = document.cookie.split(';'), caLength = cookieArray.length, c, eqIndex, name, value; + for (i = 0; i < caLength; i++) { + c = cookieArray[i]; + + // Left Trim spaces + while (c.charAt(0) === " ") { + c = c.substring(1, c.length); + } + eqIndex = c.indexOf("="); + if (eqIndex > 0) { + name = c.substring(0, eqIndex); + value = c.substring(eqIndex + 1); + postParams[name] = value; + } + } + + if (sendToFlash) { + this.setPostParams(postParams); + } + }; + +} diff -r 784ebba76424 -r 8a881c9593d0 src/ldt/ldt/media/js/swfupload/swfupload.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ldt/ldt/media/js/swfupload/swfupload.js Fri Apr 29 10:58:24 2011 +0200 @@ -0,0 +1,980 @@ +/** + * 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 + * + */ + + +/* ******************* */ +/* Constructor & Init */ +/* ******************* */ +var SWFUpload; + +if (SWFUpload == undefined) { + SWFUpload = function (settings) { + this.initSWFUpload(settings); + }; +} + +SWFUpload.prototype.initSWFUpload = function (settings) { + try { + this.customSettings = {}; // A container where developers can place their own settings associated with this instance. + this.settings = settings; + this.eventQueue = []; + this.movieName = "SWFUpload_" + SWFUpload.movieCount++; + this.movieElement = null; + + + // Setup global control tracking + SWFUpload.instances[this.movieName] = this; + + // Load the settings. Load the Flash movie. + this.initSettings(); + this.loadFlash(); + this.displayDebugInfo(); + } catch (ex) { + delete SWFUpload.instances[this.movieName]; + throw ex; + } +}; + +/* *************** */ +/* Static Members */ +/* *************** */ +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" +}; + +// Private: takes a URL, determines if it is relative and converts to an absolute URL +// using the current site. Only processes the URL if it can, otherwise returns the URL untouched +SWFUpload.completeURL = function(url) { + if (typeof(url) !== "string" || url.match(/^https?:\/\//i) || url.match(/^\//)) { + return url; + } + + var currentURL = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ":" + window.location.port : ""); + + var indexSlash = window.location.pathname.lastIndexOf("/"); + if (indexSlash <= 0) { + path = "/"; + } else { + path = window.location.pathname.substr(0, indexSlash) + "/"; + } + + return /*currentURL +*/ path + url; + +}; + + +/* ******************** */ +/* Instance Members */ +/* ******************** */ + +// Private: initSettings ensures that all the +// settings are set, getting a default value if one was not assigned. +SWFUpload.prototype.initSettings = function () { + this.ensureDefault = function (settingName, defaultValue) { + this.settings[settingName] = (this.settings[settingName] == undefined) ? defaultValue : this.settings[settingName]; + }; + + // Upload backend settings + 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); + + // File Settings + this.ensureDefault("file_types", "*.*"); + this.ensureDefault("file_types_description", "All Files"); + this.ensureDefault("file_size_limit", 0); // Default zero means "unlimited" + this.ensureDefault("file_upload_limit", 0); + this.ensureDefault("file_queue_limit", 0); + + // Flash Settings + this.ensureDefault("flash_url", "swfupload.swf"); + this.ensureDefault("prevent_swf_caching", true); + + // Button Settings + 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); + + // Debug Settings + this.ensureDefault("debug", false); + this.settings.debug_enabled = this.settings.debug; // Here to maintain v2 API + + // Event Handlers + 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", {}); + + // Other settings + this.customSettings = this.settings.custom_settings; + + // Update the flash url if needed + 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.flash_url = SWFUpload.completeURL(this.settings.flash_url); // Don't need to do this one since flash doesn't look at it + 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; +}; + +// Private: loadFlash replaces the button_placeholder element with the flash movie. +SWFUpload.prototype.loadFlash = function () { + var targetElement, tempParent; + + // Make sure an element with the ID we are going to use doesn't already exist + if (document.getElementById(this.movieName) !== null) { + throw "ID " + this.movieName + " is already in use. The Flash Object could not be added"; + } + + // Get the element where we will be placing the flash movie + targetElement = document.getElementById(this.settings.button_placeholder_id) || this.settings.button_placeholder; + + if (targetElement == undefined) { + throw "Could not find the placeholder element: " + this.settings.button_placeholder_id; + } + + // Append the container and load the flash + tempParent = document.createElement("div"); + tempParent.innerHTML = this.getFlashHTML(); // Using innerHTML is non-standard but the only sensible way to dynamically add Flash in IE (and maybe other browsers) + targetElement.parentNode.replaceChild(tempParent.firstChild, targetElement); + + // Fix IE Flash/Form bug + if (window[this.movieName] == undefined) { + window[this.movieName] = this.getMovieElement(); + } + +}; + +// Private: getFlashHTML generates the object tag needed to embed the flash in to the document +SWFUpload.prototype.getFlashHTML = function () { + // Flash Satay object syntax: http://www.alistapart.com/articles/flashsatay + return ['', + '', + '', + '', + '', + '', + '', + ''].join(""); +}; + +// Private: getFlashVars builds the parameter string that will be passed +// to flash in the flashvars param. +SWFUpload.prototype.getFlashVars = function () { + // Build a string from the post param object + var paramString = this.buildParamString(); + var httpSuccessString = this.settings.http_success.join(","); + + // Build the parameter string + 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(httpSuccessString), + "&assumeSuccessTimeout=", encodeURIComponent(this.settings.assume_success_timeout), + "&params=", encodeURIComponent(paramString), + "&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(""); +}; + +// Public: getMovieElement retrieves the DOM reference to the Flash element added by SWFUpload +// The element is cached after the first lookup +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; +}; + +// Private: buildParamString takes the name/value pairs in the post_params setting object +// and joins them up in to a string formatted "name=value&name=value" +SWFUpload.prototype.buildParamString = function () { + var postParams = this.settings.post_params; + var paramStringPairs = []; + + if (typeof(postParams) === "object") { + for (var name in postParams) { + if (postParams.hasOwnProperty(name)) { + paramStringPairs.push(encodeURIComponent(name.toString()) + "=" + encodeURIComponent(postParams[name].toString())); + } + } + } + + return paramStringPairs.join("&"); +}; + +// Public: Used to remove a SWFUpload instance from the page. This method strives to remove +// all references to the SWF, and other objects so memory is properly freed. +// Returns true if everything was destroyed. Returns a false if a failure occurs leaving SWFUpload in an inconsistant state. +// Credits: Major improvements provided by steffen +SWFUpload.prototype.destroy = function () { + try { + // Make sure Flash is done before we try to remove it + this.cancelUpload(null, false); + + + // Remove the SWFUpload DOM nodes + var movieElement = null; + movieElement = this.getMovieElement(); + + if (movieElement && typeof(movieElement.CallFunction) === "unknown") { // We only want to do this in IE + // Loop through all the movie's properties and remove all function references (DOM/JS IE 6/7 memory leak workaround) + for (var i in movieElement) { + try { + if (typeof(movieElement[i]) === "function") { + movieElement[i] = null; + } + } catch (ex1) {} + } + + // Remove the Movie Element from the page + try { + movieElement.parentNode.removeChild(movieElement); + } catch (ex) {} + } + + // Remove IE form fix reference + window[this.movieName] = null; + + // Destroy other references + 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 (ex2) { + return false; + } +}; + + +// Public: displayDebugInfo prints out settings and configuration +// information about this SWFUpload instance. +// This function (and any references to it) can be deleted when placing +// SWFUpload in production. +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("") + ); +}; + +/* Note: addSetting and getSetting are no longer used by SWFUpload but are included + the maintain v2 API compatibility +*/ +// Public: (Deprecated) addSetting adds a setting value. If the value given is undefined or null then the default_value is used. +SWFUpload.prototype.addSetting = function (name, value, default_value) { + if (value == undefined) { + return (this.settings[name] = default_value); + } else { + return (this.settings[name] = value); + } +}; + +// Public: (Deprecated) getSetting gets a setting. Returns an empty string if the setting was not found. +SWFUpload.prototype.getSetting = function (name) { + if (this.settings[name] != undefined) { + return this.settings[name]; + } + + return ""; +}; + + + +// Private: callFlash handles function calls made to the Flash element. +// Calls are made with a setTimeout for some functions to work around +// bugs in the ExternalInterface library. +SWFUpload.prototype.callFlash = function (functionName, argumentArray) { + argumentArray = argumentArray || []; + + var movieElement = this.getMovieElement(); + var returnValue, returnString; + + // Flash's method if calling ExternalInterface methods (code adapted from MooTools). + try { + returnString = movieElement.CallFunction('' + __flash__argumentsToXML(argumentArray, 0) + ''); + returnValue = eval(returnString); + } catch (ex) { + throw "Call to " + functionName + " failed"; + } + + // Unescape file post param values + if (returnValue != undefined && typeof returnValue.post === "object") { + returnValue = this.unescapeFilePostParams(returnValue); + } + + return returnValue; +}; + +/* ***************************** + -- Flash control methods -- + Your UI should use these + to operate SWFUpload + ***************************** */ + +// WARNING: this function does not work in Flash Player 10 +// Public: selectFile causes a File Selection Dialog window to appear. This +// dialog only allows 1 file to be selected. +SWFUpload.prototype.selectFile = function () { + this.callFlash("SelectFile"); +}; + +// WARNING: this function does not work in Flash Player 10 +// Public: selectFiles causes a File Selection Dialog window to appear/ This +// dialog allows the user to select any number of files +// Flash Bug Warning: Flash limits the number of selectable files based on the combined length of the file names. +// If the selection name length is too long the dialog will fail in an unpredictable manner. There is no work-around +// for this bug. +SWFUpload.prototype.selectFiles = function () { + this.callFlash("SelectFiles"); +}; + + +// Public: startUpload starts uploading the first file in the queue unless +// the optional parameter 'fileID' specifies the ID +SWFUpload.prototype.startUpload = function (fileID) { + this.callFlash("StartUpload", [fileID]); +}; + +// Public: cancelUpload cancels any queued file. The fileID parameter may be the file ID or index. +// If you do not specify a fileID the current uploading file or first file in the queue is cancelled. +// If you do not want the uploadError event to trigger you can specify false for the triggerErrorEvent parameter. +SWFUpload.prototype.cancelUpload = function (fileID, triggerErrorEvent) { + if (triggerErrorEvent !== false) { + triggerErrorEvent = true; + } + this.callFlash("CancelUpload", [fileID, triggerErrorEvent]); +}; + +// Public: stopUpload stops the current upload and requeues the file at the beginning of the queue. +// If nothing is currently uploading then nothing happens. +SWFUpload.prototype.stopUpload = function () { + this.callFlash("StopUpload"); +}; + +/* ************************ + * Settings methods + * These methods change the SWFUpload settings. + * SWFUpload settings should not be changed directly on the settings object + * since many of the settings need to be passed to Flash in order to take + * effect. + * *********************** */ + +// Public: getStats gets the file statistics object. +SWFUpload.prototype.getStats = function () { + return this.callFlash("GetStats"); +}; + +// Public: setStats changes the SWFUpload statistics. You shouldn't need to +// change the statistics but you can. Changing the statistics does not +// affect SWFUpload accept for the successful_uploads count which is used +// by the upload_limit setting to determine how many files the user may upload. +SWFUpload.prototype.setStats = function (statsObject) { + this.callFlash("SetStats", [statsObject]); +}; + +// Public: getFile retrieves a File object by ID or Index. If the file is +// not found then 'null' is returned. +SWFUpload.prototype.getFile = function (fileID) { + if (typeof(fileID) === "number") { + return this.callFlash("GetFileByIndex", [fileID]); + } else { + return this.callFlash("GetFile", [fileID]); + } +}; + +// Public: addFileParam sets a name/value pair that will be posted with the +// file specified by the Files ID. If the name already exists then the +// exiting value will be overwritten. +SWFUpload.prototype.addFileParam = function (fileID, name, value) { + return this.callFlash("AddFileParam", [fileID, name, value]); +}; + +// Public: removeFileParam removes a previously set (by addFileParam) name/value +// pair from the specified file. +SWFUpload.prototype.removeFileParam = function (fileID, name) { + this.callFlash("RemoveFileParam", [fileID, name]); +}; + +// Public: setUploadUrl changes the upload_url setting. +SWFUpload.prototype.setUploadURL = function (url) { + this.settings.upload_url = url.toString(); + this.callFlash("SetUploadURL", [url]); +}; + +// Public: setPostParams changes the post_params setting +SWFUpload.prototype.setPostParams = function (paramsObject) { + this.settings.post_params = paramsObject; + this.callFlash("SetPostParams", [paramsObject]); +}; + +// Public: addPostParam adds post name/value pair. Each name can have only one value. +SWFUpload.prototype.addPostParam = function (name, value) { + this.settings.post_params[name] = value; + this.callFlash("SetPostParams", [this.settings.post_params]); +}; + +// Public: removePostParam deletes post name/value pair. +SWFUpload.prototype.removePostParam = function (name) { + delete this.settings.post_params[name]; + this.callFlash("SetPostParams", [this.settings.post_params]); +}; + +// Public: setFileTypes changes the file_types setting and the file_types_description setting +SWFUpload.prototype.setFileTypes = function (types, description) { + this.settings.file_types = types; + this.settings.file_types_description = description; + this.callFlash("SetFileTypes", [types, description]); +}; + +// Public: setFileSizeLimit changes the file_size_limit setting +SWFUpload.prototype.setFileSizeLimit = function (fileSizeLimit) { + this.settings.file_size_limit = fileSizeLimit; + this.callFlash("SetFileSizeLimit", [fileSizeLimit]); +}; + +// Public: setFileUploadLimit changes the file_upload_limit setting +SWFUpload.prototype.setFileUploadLimit = function (fileUploadLimit) { + this.settings.file_upload_limit = fileUploadLimit; + this.callFlash("SetFileUploadLimit", [fileUploadLimit]); +}; + +// Public: setFileQueueLimit changes the file_queue_limit setting +SWFUpload.prototype.setFileQueueLimit = function (fileQueueLimit) { + this.settings.file_queue_limit = fileQueueLimit; + this.callFlash("SetFileQueueLimit", [fileQueueLimit]); +}; + +// Public: setFilePostName changes the file_post_name setting +SWFUpload.prototype.setFilePostName = function (filePostName) { + this.settings.file_post_name = filePostName; + this.callFlash("SetFilePostName", [filePostName]); +}; + +// Public: setUseQueryString changes the use_query_string setting +SWFUpload.prototype.setUseQueryString = function (useQueryString) { + this.settings.use_query_string = useQueryString; + this.callFlash("SetUseQueryString", [useQueryString]); +}; + +// Public: setRequeueOnError changes the requeue_on_error setting +SWFUpload.prototype.setRequeueOnError = function (requeueOnError) { + this.settings.requeue_on_error = requeueOnError; + this.callFlash("SetRequeueOnError", [requeueOnError]); +}; + +// Public: setHTTPSuccess changes the http_success setting +SWFUpload.prototype.setHTTPSuccess = function (http_status_codes) { + if (typeof http_status_codes === "string") { + http_status_codes = http_status_codes.replace(" ", "").split(","); + } + + this.settings.http_success = http_status_codes; + this.callFlash("SetHTTPSuccess", [http_status_codes]); +}; + +// Public: setHTTPSuccess changes the http_success setting +SWFUpload.prototype.setAssumeSuccessTimeout = function (timeout_seconds) { + this.settings.assume_success_timeout = timeout_seconds; + this.callFlash("SetAssumeSuccessTimeout", [timeout_seconds]); +}; + +// Public: setDebugEnabled changes the debug_enabled setting +SWFUpload.prototype.setDebugEnabled = function (debugEnabled) { + this.settings.debug_enabled = debugEnabled; + this.callFlash("SetDebugEnabled", [debugEnabled]); +}; + +// Public: setButtonImageURL loads a button image sprite +SWFUpload.prototype.setButtonImageURL = function (buttonImageURL) { + if (buttonImageURL == undefined) { + buttonImageURL = ""; + } + + this.settings.button_image_url = buttonImageURL; + this.callFlash("SetButtonImageURL", [buttonImageURL]); +}; + +// Public: setButtonDimensions resizes the Flash Movie and button +SWFUpload.prototype.setButtonDimensions = function (width, height) { + this.settings.button_width = width; + this.settings.button_height = height; + + var movie = this.getMovieElement(); + if (movie != undefined) { + movie.style.width = width + "px"; + movie.style.height = height + "px"; + } + + this.callFlash("SetButtonDimensions", [width, height]); +}; +// Public: setButtonText Changes the text overlaid on the button +SWFUpload.prototype.setButtonText = function (html) { + this.settings.button_text = html; + this.callFlash("SetButtonText", [html]); +}; +// Public: setButtonTextPadding changes the top and left padding of the text overlay +SWFUpload.prototype.setButtonTextPadding = function (left, top) { + this.settings.button_text_top_padding = top; + this.settings.button_text_left_padding = left; + this.callFlash("SetButtonTextPadding", [left, top]); +}; + +// Public: setButtonTextStyle changes the CSS used to style the HTML/Text overlaid on the button +SWFUpload.prototype.setButtonTextStyle = function (css) { + this.settings.button_text_style = css; + this.callFlash("SetButtonTextStyle", [css]); +}; +// Public: setButtonDisabled disables/enables the button +SWFUpload.prototype.setButtonDisabled = function (isDisabled) { + this.settings.button_disabled = isDisabled; + this.callFlash("SetButtonDisabled", [isDisabled]); +}; +// Public: setButtonAction sets the action that occurs when the button is clicked +SWFUpload.prototype.setButtonAction = function (buttonAction) { + this.settings.button_action = buttonAction; + this.callFlash("SetButtonAction", [buttonAction]); +}; + +// Public: setButtonCursor changes the mouse cursor displayed when hovering over the button +SWFUpload.prototype.setButtonCursor = function (cursor) { + this.settings.button_cursor = cursor; + this.callFlash("SetButtonCursor", [cursor]); +}; + +/* ******************************* + Flash Event Interfaces + These functions are used by Flash to trigger the various + events. + + All these functions a Private. + + Because the ExternalInterface library is buggy the event calls + are added to a queue and the queue then executed by a setTimeout. + This ensures that events are executed in a determinate order and that + the ExternalInterface bugs are avoided. +******************************* */ + +SWFUpload.prototype.queueEvent = function (handlerName, argumentArray) { + // Warning: Don't call this.debug inside here or you'll create an infinite loop + + if (argumentArray == undefined) { + argumentArray = []; + } else if (!(argumentArray instanceof Array)) { + argumentArray = [argumentArray]; + } + + var self = this; + if (typeof this.settings[handlerName] === "function") { + // Queue the event + this.eventQueue.push(function () { + this.settings[handlerName].apply(this, argumentArray); + }); + + // Execute the next queued event + setTimeout(function () { + self.executeNextEvent(); + }, 0); + + } else if (this.settings[handlerName] !== null) { + throw "Event handler " + handlerName + " is unknown or is not a function"; + } +}; + +// Private: Causes the next event in the queue to be executed. Since events are queued using a setTimeout +// we must queue them in order to garentee that they are executed in order. +SWFUpload.prototype.executeNextEvent = function () { + // Warning: Don't call this.debug inside here or you'll create an infinite loop + + var f = this.eventQueue ? this.eventQueue.shift() : null; + if (typeof(f) === "function") { + f.apply(this); + } +}; + +// Private: unescapeFileParams is part of a workaround for a flash bug where objects passed through ExternalInterface cannot have +// properties that contain characters that are not valid for JavaScript identifiers. To work around this +// the Flash Component escapes the parameter names and we must unescape again before passing them along. +SWFUpload.prototype.unescapeFilePostParams = function (file) { + var reg = /[$]([0-9a-f]{4})/i; + var unescapedPost = {}; + var uk; + + if (file != undefined) { + for (var k in file.post) { + if (file.post.hasOwnProperty(k)) { + uk = k; + var match; + while ((match = reg.exec(uk)) !== null) { + uk = uk.replace(match[0], String.fromCharCode(parseInt("0x" + match[1], 16))); + } + unescapedPost[uk] = file.post[k]; + } + } + + file.post = unescapedPost; + } + + return file; +}; + +// Private: Called by Flash to see if JS can call in to Flash (test if External Interface is working) +SWFUpload.prototype.testExternalInterface = function () { + try { + return this.callFlash("TestExternalInterface"); + } catch (ex) { + return false; + } +}; + +// Private: This event is called by Flash when it has finished loading. Don't modify this. +// Use the swfupload_loaded_handler event setting to execute custom code when SWFUpload has loaded. +SWFUpload.prototype.flashReady = function () { + // Check that the movie element is loaded correctly with its ExternalInterface methods defined + var movieElement = this.getMovieElement(); + + if (!movieElement) { + this.debug("Flash called back ready but the flash movie can't be found."); + return; + } + + this.cleanUp(movieElement); + + this.queueEvent("swfupload_loaded_handler"); +}; + +// Private: removes Flash added fuctions to the DOM node to prevent memory leaks in IE. +// This function is called by Flash each time the ExternalInterface functions are created. +SWFUpload.prototype.cleanUp = function (movieElement) { + // Pro-actively unhook all the Flash functions + try { + if (this.movieElement && typeof(movieElement.CallFunction) === "unknown") { // We only want to do this in IE + this.debug("Removing Flash functions hooks (this should only run in IE and should prevent memory leaks)"); + for (var key in movieElement) { + try { + if (typeof(movieElement[key]) === "function") { + movieElement[key] = null; + } + } catch (ex) { + } + } + } + } catch (ex1) { + + } + + // Fix Flashes own cleanup code so if the SWFMovie was removed from the page + // it doesn't display errors. + window["__flash__removeCallback"] = function (instance, name) { + try { + if (instance) { + instance[name] = null; + } + } catch (flashEx) { + + } + }; + +}; + + +/* This is a chance to do something before the browse window opens */ +SWFUpload.prototype.fileDialogStart = function () { + this.queueEvent("file_dialog_start_handler"); +}; + + +/* Called when a file is successfully added to the queue. */ +SWFUpload.prototype.fileQueued = function (file) { + file = this.unescapeFilePostParams(file); + this.queueEvent("file_queued_handler", file); +}; + + +/* Handle errors that occur when an attempt to queue a file fails. */ +SWFUpload.prototype.fileQueueError = function (file, errorCode, message) { + file = this.unescapeFilePostParams(file); + this.queueEvent("file_queue_error_handler", [file, errorCode, message]); +}; + +/* Called after the file dialog has closed and the selected files have been queued. + You could call startUpload here if you want the queued files to begin uploading immediately. */ +SWFUpload.prototype.fileDialogComplete = function (numFilesSelected, numFilesQueued, numFilesInQueue) { + this.queueEvent("file_dialog_complete_handler", [numFilesSelected, numFilesQueued, numFilesInQueue]); +}; + +SWFUpload.prototype.uploadStart = function (file) { + file = this.unescapeFilePostParams(file); + this.queueEvent("return_upload_start_handler", file); +}; + +SWFUpload.prototype.returnUploadStart = function (file) { + var returnValue; + if (typeof this.settings.upload_start_handler === "function") { + file = this.unescapeFilePostParams(file); + returnValue = this.settings.upload_start_handler.call(this, file); + } else if (this.settings.upload_start_handler != undefined) { + throw "upload_start_handler must be a function"; + } + + // Convert undefined to true so if nothing is returned from the upload_start_handler it is + // interpretted as 'true'. + if (returnValue === undefined) { + returnValue = true; + } + + returnValue = !!returnValue; + + this.callFlash("ReturnUploadStart", [returnValue]); +}; + + + +SWFUpload.prototype.uploadProgress = function (file, bytesComplete, bytesTotal) { + file = this.unescapeFilePostParams(file); + this.queueEvent("upload_progress_handler", [file, bytesComplete, bytesTotal]); +}; + +SWFUpload.prototype.uploadError = function (file, errorCode, message) { + file = this.unescapeFilePostParams(file); + this.queueEvent("upload_error_handler", [file, errorCode, message]); +}; + +SWFUpload.prototype.uploadSuccess = function (file, serverData, responseReceived) { + file = this.unescapeFilePostParams(file); + this.queueEvent("upload_success_handler", [file, serverData, responseReceived]); +}; + +SWFUpload.prototype.uploadComplete = function (file) { + file = this.unescapeFilePostParams(file); + this.queueEvent("upload_complete_handler", file); +}; + +/* Called by SWFUpload JavaScript and Flash functions when debug is enabled. By default it writes messages to the + internal debug console. You can override this event and have messages written where you want. */ +SWFUpload.prototype.debug = function (message) { + this.queueEvent("debug_handler", message); +}; + + +/* ********************************** + Debug Console + The debug console is a self contained, in page location + for debug message to be sent. The Debug Console adds + itself to the body if necessary. + + The console is automatically scrolled as messages appear. + + If you are using your own debug handler or when you deploy to production and + have debug disabled you can remove these functions to reduce the file size + and complexity. +********************************** */ + +// Private: debugMessage is the default debug_handler. If you want to print debug messages +// call the debug() function. When overriding the function your own function should +// check to see if the debug setting is true before outputting debug information. +SWFUpload.prototype.debugMessage = function (message) { + if (this.settings.debug) { + var exceptionMessage, exceptionValues = []; + + // Check for an exception object and print it nicely + if (typeof message === "object" && typeof message.name === "string" && typeof message.message === "string") { + for (var key in message) { + if (message.hasOwnProperty(key)) { + exceptionValues.push(key + ": " + message[key]); + } + } + exceptionMessage = exceptionValues.join("\n") || ""; + exceptionValues = exceptionMessage.split("\n"); + exceptionMessage = "EXCEPTION: " + exceptionValues.join("\nEXCEPTION: "); + SWFUpload.Console.writeLine(exceptionMessage); + } else { + SWFUpload.Console.writeLine(message); + } + } +}; + +SWFUpload.Console = {}; +SWFUpload.Console.writeLine = function (message) { + var console, documentForm; + + try { + console = document.getElementById("SWFUpload_Console"); + + if (!console) { + documentForm = document.createElement("form"); + document.getElementsByTagName("body")[0].appendChild(documentForm); + + console = document.createElement("textarea"); + console.id = "SWFUpload_Console"; + console.style.fontFamily = "monospace"; + console.setAttribute("wrap", "off"); + console.wrap = "off"; + console.style.overflow = "auto"; + console.style.width = "700px"; + console.style.height = "350px"; + console.style.margin = "5px"; + documentForm.appendChild(console); + } + + console.value += message + "\n"; + + console.scrollTop = console.scrollHeight - console.clientHeight; + } catch (ex) { + alert("Exception: " + ex.name + " Message: " + ex.message); + } +}; diff -r 784ebba76424 -r 8a881c9593d0 src/ldt/ldt/media/js/swfupload/swfupload.queue.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ldt/ldt/media/js/swfupload/swfupload.queue.js Fri Apr 29 10:58:24 2011 +0200 @@ -0,0 +1,98 @@ +/* + Queue Plug-in + + Features: + *Adds a cancelQueue() method for cancelling the entire queue. + *All queued files are uploaded when startUpload() is called. + *If false is returned from uploadComplete then the queue upload is stopped. + If false is not returned (strict comparison) then the queue upload is continued. + *Adds a QueueComplete event that is fired when all the queued files have finished uploading. + Set the event handler with the queue_complete_handler setting. + + */ + +var SWFUpload; +if (typeof(SWFUpload) === "function") { + SWFUpload.queue = {}; + + SWFUpload.prototype.initSettings = (function (oldInitSettings) { + return function () { + if (typeof(oldInitSettings) === "function") { + oldInitSettings.call(this); + } + + this.queueSettings = {}; + + this.queueSettings.queue_cancelled_flag = false; + this.queueSettings.queue_upload_count = 0; + + this.queueSettings.user_upload_complete_handler = this.settings.upload_complete_handler; + this.queueSettings.user_upload_start_handler = this.settings.upload_start_handler; + this.settings.upload_complete_handler = SWFUpload.queue.uploadCompleteHandler; + this.settings.upload_start_handler = SWFUpload.queue.uploadStartHandler; + + this.settings.queue_complete_handler = this.settings.queue_complete_handler || null; + }; + })(SWFUpload.prototype.initSettings); + + SWFUpload.prototype.startUpload = function (fileID) { + this.queueSettings.queue_cancelled_flag = false; + this.callFlash("StartUpload", [fileID]); + }; + + SWFUpload.prototype.cancelQueue = function () { + this.queueSettings.queue_cancelled_flag = true; + this.stopUpload(); + + var stats = this.getStats(); + while (stats.files_queued > 0) { + this.cancelUpload(); + stats = this.getStats(); + } + }; + + SWFUpload.queue.uploadStartHandler = function (file) { + var returnValue; + if (typeof(this.queueSettings.user_upload_start_handler) === "function") { + returnValue = this.queueSettings.user_upload_start_handler.call(this, file); + } + + // To prevent upload a real "FALSE" value must be returned, otherwise default to a real "TRUE" value. + returnValue = (returnValue === false) ? false : true; + + this.queueSettings.queue_cancelled_flag = !returnValue; + + return returnValue; + }; + + SWFUpload.queue.uploadCompleteHandler = function (file) { + var user_upload_complete_handler = this.queueSettings.user_upload_complete_handler; + var continueUpload; + + if (file.filestatus === SWFUpload.FILE_STATUS.COMPLETE) { + this.queueSettings.queue_upload_count++; + } + + if (typeof(user_upload_complete_handler) === "function") { + continueUpload = (user_upload_complete_handler.call(this, file) === false) ? false : true; + } else if (file.filestatus === SWFUpload.FILE_STATUS.QUEUED) { + // If the file was stopped and re-queued don't restart the upload + continueUpload = false; + } else { + continueUpload = true; + } + + if (continueUpload) { + var stats = this.getStats(); + if (stats.files_queued > 0 && this.queueSettings.queue_cancelled_flag === false) { + this.startUpload(); + } else if (this.queueSettings.queue_cancelled_flag === false) { + this.queueEvent("queue_complete_handler", [this.queueSettings.queue_upload_count]); + this.queueSettings.queue_upload_count = 0; + } else { + this.queueSettings.queue_cancelled_flag = false; + this.queueSettings.queue_upload_count = 0; + } + } + }; +} \ No newline at end of file diff -r 784ebba76424 -r 8a881c9593d0 src/ldt/ldt/media/js/swfupload/swfupload.speed.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ldt/ldt/media/js/swfupload/swfupload.speed.js Fri Apr 29 10:58:24 2011 +0200 @@ -0,0 +1,342 @@ +/* + Speed Plug-in + + Features: + *Adds several properties to the 'file' object indicated upload speed, time left, upload time, etc. + - currentSpeed -- String indicating the upload speed, bytes per second + - averageSpeed -- Overall average upload speed, bytes per second + - movingAverageSpeed -- Speed over averaged over the last several measurements, bytes per second + - timeRemaining -- Estimated remaining upload time in seconds + - timeElapsed -- Number of seconds passed for this upload + - percentUploaded -- Percentage of the file uploaded (0 to 100) + - sizeUploaded -- Formatted size uploaded so far, bytes + + *Adds setting 'moving_average_history_size' for defining the window size used to calculate the moving average speed. + + *Adds several Formatting functions for formatting that values provided on the file object. + - SWFUpload.speed.formatBPS(bps) -- outputs string formatted in the best units (Gbps, Mbps, Kbps, bps) + - SWFUpload.speed.formatTime(seconds) -- outputs string formatted in the best units (x Hr y M z S) + - SWFUpload.speed.formatSize(bytes) -- outputs string formatted in the best units (w GB x MB y KB z B ) + - SWFUpload.speed.formatPercent(percent) -- outputs string formatted with a percent sign (x.xx %) + - SWFUpload.speed.formatUnits(baseNumber, divisionArray, unitLabelArray, fractionalBoolean) + - Formats a number using the division array to determine how to apply the labels in the Label Array + - factionalBoolean indicates whether the number should be returned as a single fractional number with a unit (speed) + or as several numbers labeled with units (time) + */ + +var SWFUpload; +if (typeof(SWFUpload) === "function") { + SWFUpload.speed = {}; + + SWFUpload.prototype.initSettings = (function (oldInitSettings) { + return function () { + if (typeof(oldInitSettings) === "function") { + oldInitSettings.call(this); + } + + this.ensureDefault = function (settingName, defaultValue) { + this.settings[settingName] = (this.settings[settingName] == undefined) ? defaultValue : this.settings[settingName]; + }; + + // List used to keep the speed stats for the files we are tracking + this.fileSpeedStats = {}; + this.speedSettings = {}; + + this.ensureDefault("moving_average_history_size", "10"); + + this.speedSettings.user_file_queued_handler = this.settings.file_queued_handler; + this.speedSettings.user_file_queue_error_handler = this.settings.file_queue_error_handler; + this.speedSettings.user_upload_start_handler = this.settings.upload_start_handler; + this.speedSettings.user_upload_error_handler = this.settings.upload_error_handler; + this.speedSettings.user_upload_progress_handler = this.settings.upload_progress_handler; + this.speedSettings.user_upload_success_handler = this.settings.upload_success_handler; + this.speedSettings.user_upload_complete_handler = this.settings.upload_complete_handler; + + this.settings.file_queued_handler = SWFUpload.speed.fileQueuedHandler; + this.settings.file_queue_error_handler = SWFUpload.speed.fileQueueErrorHandler; + this.settings.upload_start_handler = SWFUpload.speed.uploadStartHandler; + this.settings.upload_error_handler = SWFUpload.speed.uploadErrorHandler; + this.settings.upload_progress_handler = SWFUpload.speed.uploadProgressHandler; + this.settings.upload_success_handler = SWFUpload.speed.uploadSuccessHandler; + this.settings.upload_complete_handler = SWFUpload.speed.uploadCompleteHandler; + + delete this.ensureDefault; + }; + })(SWFUpload.prototype.initSettings); + + + SWFUpload.speed.fileQueuedHandler = function (file) { + if (typeof this.speedSettings.user_file_queued_handler === "function") { + file = SWFUpload.speed.extendFile(file); + + return this.speedSettings.user_file_queued_handler.call(this, file); + } + }; + + SWFUpload.speed.fileQueueErrorHandler = function (file, errorCode, message) { + if (typeof this.speedSettings.user_file_queue_error_handler === "function") { + file = SWFUpload.speed.extendFile(file); + + return this.speedSettings.user_file_queue_error_handler.call(this, file, errorCode, message); + } + }; + + SWFUpload.speed.uploadStartHandler = function (file) { + if (typeof this.speedSettings.user_upload_start_handler === "function") { + file = SWFUpload.speed.extendFile(file, this.fileSpeedStats); + return this.speedSettings.user_upload_start_handler.call(this, file); + } + }; + + SWFUpload.speed.uploadErrorHandler = function (file, errorCode, message) { + file = SWFUpload.speed.extendFile(file, this.fileSpeedStats); + SWFUpload.speed.removeTracking(file, this.fileSpeedStats); + + if (typeof this.speedSettings.user_upload_error_handler === "function") { + return this.speedSettings.user_upload_error_handler.call(this, file, errorCode, message); + } + }; + SWFUpload.speed.uploadProgressHandler = function (file, bytesComplete, bytesTotal) { + this.updateTracking(file, bytesComplete); + file = SWFUpload.speed.extendFile(file, this.fileSpeedStats); + + if (typeof this.speedSettings.user_upload_progress_handler === "function") { + return this.speedSettings.user_upload_progress_handler.call(this, file, bytesComplete, bytesTotal); + } + }; + + SWFUpload.speed.uploadSuccessHandler = function (file, serverData) { + if (typeof this.speedSettings.user_upload_success_handler === "function") { + file = SWFUpload.speed.extendFile(file, this.fileSpeedStats); + return this.speedSettings.user_upload_success_handler.call(this, file, serverData); + } + }; + SWFUpload.speed.uploadCompleteHandler = function (file) { + file = SWFUpload.speed.extendFile(file, this.fileSpeedStats); + SWFUpload.speed.removeTracking(file, this.fileSpeedStats); + + if (typeof this.speedSettings.user_upload_complete_handler === "function") { + return this.speedSettings.user_upload_complete_handler.call(this, file); + } + }; + + // Private: extends the file object with the speed plugin values + SWFUpload.speed.extendFile = function (file, trackingList) { + var tracking; + + if (trackingList) { + tracking = trackingList[file.id]; + } + + if (tracking) { + file.currentSpeed = tracking.currentSpeed; + file.averageSpeed = tracking.averageSpeed; + file.movingAverageSpeed = tracking.movingAverageSpeed; + file.timeRemaining = tracking.timeRemaining; + file.timeElapsed = tracking.timeElapsed; + file.percentUploaded = tracking.percentUploaded; + file.sizeUploaded = tracking.bytesUploaded; + + } else { + file.currentSpeed = 0; + file.averageSpeed = 0; + file.movingAverageSpeed = 0; + file.timeRemaining = 0; + file.timeElapsed = 0; + file.percentUploaded = 0; + file.sizeUploaded = 0; + } + + return file; + }; + + // Private: Updates the speed tracking object, or creates it if necessary + SWFUpload.prototype.updateTracking = function (file, bytesUploaded) { + var tracking = this.fileSpeedStats[file.id]; + if (!tracking) { + this.fileSpeedStats[file.id] = tracking = {}; + } + + // Sanity check inputs + bytesUploaded = bytesUploaded || tracking.bytesUploaded || 0; + if (bytesUploaded < 0) { + bytesUploaded = 0; + } + if (bytesUploaded > file.size) { + bytesUploaded = file.size; + } + + var tickTime = (new Date()).getTime(); + if (!tracking.startTime) { + tracking.startTime = (new Date()).getTime(); + tracking.lastTime = tracking.startTime; + tracking.currentSpeed = 0; + tracking.averageSpeed = 0; + tracking.movingAverageSpeed = 0; + tracking.movingAverageHistory = []; + tracking.timeRemaining = 0; + tracking.timeElapsed = 0; + tracking.percentUploaded = bytesUploaded / file.size; + tracking.bytesUploaded = bytesUploaded; + } else if (tracking.startTime > tickTime) { + this.debug("When backwards in time"); + } else { + // Get time and deltas + var now = (new Date()).getTime(); + var lastTime = tracking.lastTime; + var deltaTime = now - lastTime; + var deltaBytes = bytesUploaded - tracking.bytesUploaded; + + if (deltaBytes === 0 || deltaTime === 0) { + return tracking; + } + + // Update tracking object + tracking.lastTime = now; + tracking.bytesUploaded = bytesUploaded; + + // Calculate speeds + tracking.currentSpeed = (deltaBytes * 8 ) / (deltaTime / 1000); + tracking.averageSpeed = (tracking.bytesUploaded * 8) / ((now - tracking.startTime) / 1000); + + // Calculate moving average + tracking.movingAverageHistory.push(tracking.currentSpeed); + if (tracking.movingAverageHistory.length > this.settings.moving_average_history_size) { + tracking.movingAverageHistory.shift(); + } + + tracking.movingAverageSpeed = SWFUpload.speed.calculateMovingAverage(tracking.movingAverageHistory); + + // Update times + tracking.timeRemaining = (file.size - tracking.bytesUploaded) * 8 / tracking.movingAverageSpeed; + tracking.timeElapsed = (now - tracking.startTime) / 1000; + + // Update percent + tracking.percentUploaded = (tracking.bytesUploaded / file.size * 100); + } + + return tracking; + }; + SWFUpload.speed.removeTracking = function (file, trackingList) { + try { + trackingList[file.id] = null; + delete trackingList[file.id]; + } catch (ex) { + } + }; + + SWFUpload.speed.formatUnits = function (baseNumber, unitDivisors, unitLabels, singleFractional) { + var i, unit, unitDivisor, unitLabel; + + if (baseNumber === 0) { + return "0 " + unitLabels[unitLabels.length - 1]; + } + + if (singleFractional) { + unit = baseNumber; + unitLabel = unitLabels.length >= unitDivisors.length ? unitLabels[unitDivisors.length - 1] : ""; + for (i = 0; i < unitDivisors.length; i++) { + if (baseNumber >= unitDivisors[i]) { + unit = (baseNumber / unitDivisors[i]).toFixed(2); + unitLabel = unitLabels.length >= i ? " " + unitLabels[i] : ""; + break; + } + } + + return unit + unitLabel; + } else { + var formattedStrings = []; + var remainder = baseNumber; + + for (i = 0; i < unitDivisors.length; i++) { + unitDivisor = unitDivisors[i]; + unitLabel = unitLabels.length > i ? " " + unitLabels[i] : ""; + + unit = remainder / unitDivisor; + if (i < unitDivisors.length -1) { + unit = Math.floor(unit); + } else { + unit = unit.toFixed(2); + } + if (unit > 0) { + remainder = remainder % unitDivisor; + + formattedStrings.push(unit + unitLabel); + } + } + + return formattedStrings.join(" "); + } + }; + + SWFUpload.speed.formatBPS = function (baseNumber) { + var bpsUnits = [1073741824, 1048576, 1024, 1], bpsUnitLabels = ["Gbps", "Mbps", "Kbps", "bps"]; + return SWFUpload.speed.formatUnits(baseNumber, bpsUnits, bpsUnitLabels, true); + + }; + SWFUpload.speed.formatTime = function (baseNumber) { + var timeUnits = [86400, 3600, 60, 1], timeUnitLabels = ["d", "h", "m", "s"]; + return SWFUpload.speed.formatUnits(baseNumber, timeUnits, timeUnitLabels, false); + + }; + SWFUpload.speed.formatBytes = function (baseNumber) { + var sizeUnits = [1073741824, 1048576, 1024, 1], sizeUnitLabels = ["GB", "MB", "KB", "bytes"]; + return SWFUpload.speed.formatUnits(baseNumber, sizeUnits, sizeUnitLabels, true); + + }; + SWFUpload.speed.formatPercent = function (baseNumber) { + return baseNumber.toFixed(2) + " %"; + }; + + SWFUpload.speed.calculateMovingAverage = function (history) { + var vals = [], size, sum = 0.0, mean = 0.0, varianceTemp = 0.0, variance = 0.0, standardDev = 0.0; + var i; + var mSum = 0, mCount = 0; + + size = history.length; + + // Check for sufficient data + if (size >= 8) { + // Clone the array and Calculate sum of the values + for (i = 0; i < size; i++) { + vals[i] = history[i]; + sum += vals[i]; + } + + mean = sum / size; + + // Calculate variance for the set + for (i = 0; i < size; i++) { + varianceTemp += Math.pow((vals[i] - mean), 2); + } + + variance = varianceTemp / size; + standardDev = Math.sqrt(variance); + + //Standardize the Data + for (i = 0; i < size; i++) { + vals[i] = (vals[i] - mean) / standardDev; + } + + // Calculate the average excluding outliers + var deviationRange = 2.0; + for (i = 0; i < size; i++) { + + if (vals[i] <= deviationRange && vals[i] >= -deviationRange) { + mCount++; + mSum += history[i]; + } + } + + } else { + // Calculate the average (not enough data points to remove outliers) + mCount = size; + for (i = 0; i < size; i++) { + mSum += history[i]; + } + } + + return mSum / mCount; + }; + +} \ No newline at end of file diff -r 784ebba76424 -r 8a881c9593d0 src/ldt/ldt/media/js/swfupload/swfupload.swfobject.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ldt/ldt/media/js/swfupload/swfupload.swfobject.js Fri Apr 29 10:58:24 2011 +0200 @@ -0,0 +1,111 @@ +/* + SWFUpload.SWFObject Plugin + + Summary: + This plugin uses SWFObject to embed SWFUpload dynamically in the page. SWFObject provides accurate Flash Player detection and DOM Ready loading. + This plugin replaces the Graceful Degradation plugin. + + Features: + * swfupload_load_failed_hander event + * swfupload_pre_load_handler event + * minimum_flash_version setting (default: "9.0.28") + * SWFUpload.onload event for early loading + + Usage: + Provide handlers and settings as needed. When using the SWFUpload.SWFObject plugin you should initialize SWFUploading + in SWFUpload.onload rather than in window.onload. When initialized this way SWFUpload can load earlier preventing the UI flicker + that was seen using the Graceful Degradation plugin. + + + + Notes: + You must provide set minimum_flash_version setting to "8" if you are using SWFUpload for Flash Player 8. + The swfuploadLoadFailed event is only fired if the minimum version of Flash Player is not met. Other issues such as missing SWF files, browser bugs + or corrupt Flash Player installations will not trigger this event. + The swfuploadPreLoad event is fired as soon as the minimum version of Flash Player is found. It does not wait for SWFUpload to load and can + be used to prepare the SWFUploadUI and hide alternate content. + swfobject's onDomReady event is cross-browser safe but will default to the window.onload event when DOMReady is not supported by the browser. + Early DOM Loading is supported in major modern browsers but cannot be guaranteed for every browser ever made. +*/ + + +/* SWFObject v2.1 + Copyright (c) 2007-2008 Geoff Stearns, Michael Williams, and Bobby van der Sluis + This software is released under the MIT License +*/ +var swfobject=function(){var b="undefined",Q="object",n="Shockwave Flash",p="ShockwaveFlash.ShockwaveFlash",P="application/x-shockwave-flash",m="SWFObjectExprInst",j=window,K=document,T=navigator,o=[],N=[],i=[],d=[],J,Z=null,M=null,l=null,e=false,A=false;var h=function(){var v=typeof K.getElementById!=b&&typeof K.getElementsByTagName!=b&&typeof K.createElement!=b,AC=[0,0,0],x=null;if(typeof T.plugins!=b&&typeof T.plugins[n]==Q){x=T.plugins[n].description;if(x&&!(typeof T.mimeTypes!=b&&T.mimeTypes[P]&&!T.mimeTypes[P].enabledPlugin)){x=x.replace(/^.*\s+(\S+\s+\S+$)/,"$1");AC[0]=parseInt(x.replace(/^(.*)\..*$/,"$1"),10);AC[1]=parseInt(x.replace(/^.*\.(.*)\s.*$/,"$1"),10);AC[2]=/r/.test(x)?parseInt(x.replace(/^.*r(.*)$/,"$1"),10):0}}else{if(typeof j.ActiveXObject!=b){var y=null,AB=false;try{y=new ActiveXObject(p+".7")}catch(t){try{y=new ActiveXObject(p+".6");AC=[6,0,21];y.AllowScriptAccess="always"}catch(t){if(AC[0]==6){AB=true}}if(!AB){try{y=new ActiveXObject(p)}catch(t){}}}if(!AB&&y){try{x=y.GetVariable("$version");if(x){x=x.split(" ")[1].split(",");AC=[parseInt(x[0],10),parseInt(x[1],10),parseInt(x[2],10)]}}catch(t){}}}}var AD=T.userAgent.toLowerCase(),r=T.platform.toLowerCase(),AA=/webkit/.test(AD)?parseFloat(AD.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,q=false,z=r?/win/.test(r):/win/.test(AD),w=r?/mac/.test(r):/mac/.test(AD);/*@cc_on q=true;@if(@_win32)z=true;@elif(@_mac)w=true;@end@*/return{w3cdom:v,pv:AC,webkit:AA,ie:q,win:z,mac:w}}();var L=function(){if(!h.w3cdom){return }f(H);if(h.ie&&h.win){try{K.write(" + + Notes: + You must provide set minimum_flash_version setting to "8" if you are using SWFUpload for Flash Player 8. + The swfuploadLoadFailed event is only fired if the minimum version of Flash Player is not met. Other issues such as missing SWF files, browser bugs + or corrupt Flash Player installations will not trigger this event. + The swfuploadPreLoad event is fired as soon as the minimum version of Flash Player is found. It does not wait for SWFUpload to load and can + be used to prepare the SWFUploadUI and hide alternate content. + swfobject's onDomReady event is cross-browser safe but will default to the window.onload event when DOMReady is not supported by the browser. + Early DOM Loading is supported in major modern browsers but cannot be guaranteed for every browser ever made. +*/ + + +/* SWFObject v2.1 + Copyright (c) 2007-2008 Geoff Stearns, Michael Williams, and Bobby van der Sluis + This software is released under the MIT License +*/ +var swfobject=function(){var b="undefined",Q="object",n="Shockwave Flash",p="ShockwaveFlash.ShockwaveFlash",P="application/x-shockwave-flash",m="SWFObjectExprInst",j=window,K=document,T=navigator,o=[],N=[],i=[],d=[],J,Z=null,M=null,l=null,e=false,A=false;var h=function(){var v=typeof K.getElementById!=b&&typeof K.getElementsByTagName!=b&&typeof K.createElement!=b,AC=[0,0,0],x=null;if(typeof T.plugins!=b&&typeof T.plugins[n]==Q){x=T.plugins[n].description;if(x&&!(typeof T.mimeTypes!=b&&T.mimeTypes[P]&&!T.mimeTypes[P].enabledPlugin)){x=x.replace(/^.*\s+(\S+\s+\S+$)/,"$1");AC[0]=parseInt(x.replace(/^(.*)\..*$/,"$1"),10);AC[1]=parseInt(x.replace(/^.*\.(.*)\s.*$/,"$1"),10);AC[2]=/r/.test(x)?parseInt(x.replace(/^.*r(.*)$/,"$1"),10):0}}else{if(typeof j.ActiveXObject!=b){var y=null,AB=false;try{y=new ActiveXObject(p+".7")}catch(t){try{y=new ActiveXObject(p+".6");AC=[6,0,21];y.AllowScriptAccess="always"}catch(t){if(AC[0]==6){AB=true}}if(!AB){try{y=new ActiveXObject(p)}catch(t){}}}if(!AB&&y){try{x=y.GetVariable("$version");if(x){x=x.split(" ")[1].split(",");AC=[parseInt(x[0],10),parseInt(x[1],10),parseInt(x[2],10)]}}catch(t){}}}}var AD=T.userAgent.toLowerCase(),r=T.platform.toLowerCase(),AA=/webkit/.test(AD)?parseFloat(AD.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,q=false,z=r?/win/.test(r):/win/.test(AD),w=r?/mac/.test(r):/mac/.test(AD);/*@cc_on q=true;@if(@_win32)z=true;@elif(@_mac)w=true;@end@*/return{w3cdom:v,pv:AC,webkit:AA,ie:q,win:z,mac:w}}();var L=function(){if(!h.w3cdom){return }f(H);if(h.ie&&h.win){try{K.write("