# HG changeset patch # User rougeronj # Date 1354290026 -3600 # Node ID 380d3657bc2861c030bb8656f467df0a11d0625a # Parent 232d40ae99d03bf6861d979f02d006d0b8859a35# Parent 9f7680957db8f7501d7d48a304545c0920b45349 Merge with 9f7680957db8f7501d7d48a304545c0920b45349 diff -r 9f7680957db8 -r 380d3657bc28 .DS_Store Binary file .DS_Store has changed diff -r 9f7680957db8 -r 380d3657bc28 .hgignore --- a/.hgignore Fri Nov 30 11:59:47 2012 +0100 +++ b/.hgignore Fri Nov 30 16:40:26 2012 +0100 @@ -1,19 +1,8 @@ syntax: regexp -^web/index$ -^web/log$ -^virtualenv/web/env/ .*\.pyc$ -^virtualenv/web/project-boot\.py$ -^web/ldtplatform/config\.py$ -^web/ldtplatform/\.htaccess$ -^web/\.htaccess$ -^virtualenv/web/distribute-0\.6\.14\.tar\.gz$ ^src/ldt/Ldt\.egg-info$ ^src/ldt/dist$ -^web/static/media/ldt$ -^web/static/site/admin$ -^web/static/site/ldt$ ^virtualenv/setup/project-boot\.py$ ^virtualenv/setup/env/ ^src/ldt/build$ @@ -23,16 +12,5 @@ ^src/ldt/MANIFEST\.in$ ^src/ldt/MANIFEST$ ^\.pydevproject$ -^web/static/media/cache$ ^\.settings/org\.eclipse\.core\.resources\.prefs$ -^web/static/media/thumbnails$ -^virtualenv/sync/env - -syntax: regexp -^sbin/sync/config\.py$ -syntax: regexp -^virtualenv/sync/project-boot\.py$ -relre:^.metadata - -syntax: regexp -^web/\.htusers$ \ No newline at end of file +\.DS_Store$ diff -r 9f7680957db8 -r 380d3657bc28 .hgtags --- a/.hgtags Fri Nov 30 11:59:47 2012 +0100 +++ b/.hgtags Fri Nov 30 16:40:26 2012 +0100 @@ -126,3 +126,11 @@ 19fb9bcc6bc51ffa132f75d33d8eadf8acd1164f V01.30 d49f0e0e0a52880228a8bf83e75ad02971db569e V01.30 ba35e8803c76b87d68a4c95f180cebf35d71b73f V01.31 +10b2e464af09e56809b3c9e4209f88297fa7f5c0 V01.32 +caa3a2695cb7710bbab7970ebd0e0b28eea140a9 V01.33 +caa3a2695cb7710bbab7970ebd0e0b28eea140a9 V01.33 +41eb88128c8fad65408b2db4965ffda6c75d21bc V01.33 +659ca382a67d90fd7fdda8c4f422091434c97d86 V01.34 +a05ad02125c58e419fcbd52475c9f39be35f576e V01.35 +a774af5e10f40b65dd1ec748ad36e9ed4e9a294e V01.36 +89e3320ac56c863333e3e5317d1c7fced478cc05 V01.36 diff -r 9f7680957db8 -r 380d3657bc28 .settings/org.eclipse.core.resources.prefs --- a/.settings/org.eclipse.core.resources.prefs Fri Nov 30 11:59:47 2012 +0100 +++ b/.settings/org.eclipse.core.resources.prefs Fri Nov 30 16:40:26 2012 +0100 @@ -38,7 +38,4 @@ encoding//src/ldt/ldt/user/migrations/0001_initial.py=utf-8 encoding//src/ldt/ldt/user/migrations/0008_auto__chg_field_groupprofile_image__chg_field_groupprofile_group__chg_.py=utf-8 encoding//virtualenv/web/env/guardianenv/Lib/site-packages/guardian/migrations/0001_initial.py=utf-8 -encoding//virtualenv/web/env/venv_platform/lib/python2.7/site-packages/haystack/backends/__init__.py=utf-8 -encoding//web/ldtplatform/config.py=utf-8 -encoding//web/ldtplatform/settings.py=utf-8 encoding/=UTF-8 diff -r 9f7680957db8 -r 380d3657bc28 sbin/sync/config.py.tmpl --- a/sbin/sync/config.py.tmpl Fri Nov 30 11:59:47 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -from fabric.api import env - -env.hosts = ['iri@web.iri.centrepompidou.fr'] - -env.web_group = 'www-data' -env.folders = ['log', 'static/media'] - -env.base_export_path = "~/tmp" -env.export_prefix = "platform" -env.remote_web_path = "/iridata/www/ldt/" -env.platform_web_module = "ldtplatform" -env.remote_ldt_base_path = "/tmp" -env.remote_virtualenv_path = "/iridata/virtualenv/ldt" -env.remote_venv_export_path = "/iridata/users/iri/tmp" -env.remote_baseline_venv = "/iridata/virtualenv/baseline2.7" -env.web_rsync_filters = [ - "+ core", - "P .htpasswd", - "P .htaccess", - "P ldtplatform/.htaccess", - "P ldtplatform/config.py", - "P ldtplatform/modwsgi.wsgi", - "P robots.txt", - "P env/***", - "P log/***", - "P index/***", - "P static/media/***", - "P crossdomain.xml", -] -env.venv_rsync_filters = [ - "+ core", -] -env.web_relaunch_cmd = "supervisorctl restart platform" - -env.base_url = "/" -env.web_url = "http://ldt.iri.centrepompidou.fr" -env.stream_url = "rtmp://media.iri.centrepompidou.fr/ddc_player/" - -env.stream_src_prefix = "" -env.ffmpeg_path = "/usr/bin/ffmpeg" - -env.db_engine = 'django.db.backends.postgresql_psycopg2' -env.db_name = 'platform' -env.db_user = 'iriuser' -env.db_password = '' -env.db_host = 'sql.iri.centrepompidou.fr' -env.db_port = 5432 - -env.log_file = env.remote_web_path + '/log/log.txt' - -env.google_analytics_code = "" - -env.email_use_tls = True -env.email_host = "" -env.email_host_user = "" -env.email_host_user = "" -env.email_port = "" - -env.forbidden_stream_url = "rtmp://media.iri.centrepompidou.fr/ddc_player/mp4:video/forbidden_stream.mp4?old_path=" - diff -r 9f7680957db8 -r 380d3657bc28 sbin/sync/fabfile.py --- a/sbin/sync/fabfile.py Fri Nov 30 11:59:47 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,282 +0,0 @@ -from fabric.api import task, run, local, env, cd, put, prefix, sudo -from fabric.colors import green -from fabric.contrib.project import rsync_project -from fabric.contrib.files import exists, upload_template -from fabric.context_managers import settings -from mercurial import commands, ui, hg, cmdutil -import imp -import os, os.path -import shutil -import sys - -import config - -def get_export_path(version): - base_path = os.path.join(env.base_export_path,env.export_prefix).rstrip("/") - return os.path.expanduser(base_path) + "_%s" % (str(version)) - -def clean_export_folder(path): - print("Removing %s" % path) - if os.path.isdir(path): - shutil.rmtree(path, ignore_errors=True) - -def do_export_version(path, version): - print("Export version %s"%str(version)) - - local("hg archive -r \'%s\' \"%s\"" % (str(version),path)) - print("Export version %s done"%str(version)) - - -def get_remote_env(remotepath, remotevirtualenvpath, platform_web_module, settings_key): - activate_path = os.path.join(remotevirtualenvpath, "bin/activate") - res = "" - with prefix("source \"%s\"" % activate_path), prefix("export PYTHONPATH=\"%s\"" % remotepath), cd(remotepath): - tempfilepath = run("mktemp -t ldtplatform.XXXXXX") - with settings(warn_only=True): - run("echo \"import os\" > %s" % (tempfilepath)) - map(lambda str: run("echo \"%s\" >> %s" % (str, tempfilepath)), - ["os.environ.setdefault('DJANGO_SETTINGS_MODULE', '%s.settings')" % (platform_web_module), - "from django.conf import settings", - "print settings.%s" % (settings_key)]) - res = run("python < %s" % (tempfilepath)) - run("rm -f \"%s\"" % (tempfilepath)) - return res - - - -def rsync_export(path, remotepath, filters): - print("Rsync %s to %s",(path,remotepath)) - - filter_option_str = "--progress --stats" - if filters: - filter_option_str += " " + " ".join(["--filter \"%s\"" % (f) for f in filters]) - - run("mkdir -p \"%s\"" % remotepath) - rsync_project(remotepath, local_dir=path, extra_opts=filter_option_str, delete=True) - print("Rsync %s to %s done",(path,remotepath)) - -def clean_rsync_folder(remotepath): - print("clean rsync folder %s" % remotepath) - run("rm -fr \"%s\"" % remotepath) - -def build_src(path): - print("Build source dist at %s" % path) - f = None - try: - f, pathname, description = imp.find_module("setup", [path]) - print(" 2 Build source dist at %s" % path) - setup_mod = imp.load_module("setup", f, pathname, description) - print(" 3 Build source dist at %s" % path) - finally: - if f: - f.close() - - setup_mod.launch_setup("setup.py", ['sdist']) - - print("Build source dist at %s done" % path) - - -def get_src_version(path): - print("get src version at %s" % path) - f = None - try: - f, pathname, description = imp.find_module("ldt", [path]) - ldt_mod = imp.load_module("ldt", f, pathname, description) - finally: - if f: - f.close() - version = ldt_mod.VERSION - version_str = ldt_mod.get_version() - - return (version, version_str) - - -def sync_build(path): - print("Sync build %s" % path) - with cd(env.remote_ldt_base_path): - filename = os.path.basename(path) - res_trans = put(path, os.path.join(env.remote_ldt_base_path, filename)) - print("Sync build %s to %s" % (path,repr(res_trans))) - return res_trans - -def remove_build(path): - print("remove build build %s" % path) - run("rm \"%s\"" % path) - - -def install_build(remotepath, remotevirtualenvpath): - print("Install build %s in %s" % (remotepath, remotevirtualenvpath)) - activate_path = os.path.join(remotevirtualenvpath, "bin/activate") - - with prefix("source %s" % activate_path): - run("pip install \"%s\"" % remotepath) - -def collectstatic(remotepath, remotevirtualenvpath, platform_web_module): - print("Collect static in %s with %s" % (remotepath, remotevirtualenvpath)) - remotestaticsitepath = get_remote_env(remotepath, remotevirtualenvpath, platform_web_module, "STATIC_ROOT") - activate_path = os.path.join(remotevirtualenvpath, "bin/activate") - with prefix("source \"%s\"" % activate_path), prefix("export PYTHONPATH=\"%s\"" % remotepath), cd(remotepath): - #remocve old files optio -c of collect static fail ! - run("rm -fr \"%s\"" % (remotestaticsitepath)) - run("python manage.py collectstatic --noinput") - -def create_config(export_path): - print("Create config from %s" % (export_path,)) - remotepath = env.remote_web_path - remote_config_path = os.path.join(remotepath, env.platform_web_module, "config.py") - template_path = os.path.join(export_path, "web", env.platform_web_module, "config.py.tmpl") - - context = { - 'base_dir': os.path.join(remotepath, env.platform_web_module).rstrip("/")+"/", - 'base_url': env.base_url, - 'web_url': env.web_url, - 'stream_url': env.stream_url, - 'stream_src_prefix': env.stream_src_prefix, - 'ffmpeg_path': env.ffmpeg_path, - 'db_engine': env.db_engine, - 'db_name': env.db_name, - 'db_user': env.db_user, - 'db_password': env.db_password, - 'db_host': env.db_host, - 'db_port': env.db_port, - 'log_file': env.log_file, - 'google_analytics_code': env.google_analytics_code, - 'email_use_tls': env.email_use_tls, - 'email_host': env.email_host, - 'email_host_user': env.email_host_user, - 'email_host_user': env.email_host_user, - 'email_port': env.email_port, - 'forbidden_stream_url': env.forbidden_stream_url, - } - - if not exists(remote_config_path, verbose=True): - upload_template(template_path, remote_config_path, context=context) - -def export_version(version): - print("export version %s" % str(version)) - - export_path = get_export_path(version) - - clean_export_folder(export_path) - do_export_version(export_path,version) - - return export_path - -def do_create_virtualenv(remote_venv_export_path, remotevirtualenvpath): - print("Create virtualenv export_path : %s - remote venvpath : %s" % (remote_venv_export_path, remotevirtualenvpath)) - activate_path = os.path.join(remotevirtualenvpath, "bin/activate") - if "remote_baseline_venv" in env and env.remote_baseline_venv: - prefix_str = "source \"%s\"" % os.path.join(env.remote_baseline_venv, "bin/activate") - else: - prefix_str = "echo" - with settings(warn_only=True): - run("rm -fr \"%s\"" % remotevirtualenvpath) - run("mkdir -p \"%s\"" % remotevirtualenvpath) - with prefix(prefix_str), cd(os.path.join(remote_venv_export_path,"virtualenv","web")): - run("python create_python_env.py") - run("python project-boot.py \"%s\"" % remotevirtualenvpath) - with prefix("source \"%s\"" % activate_path): - run("pip install -r \"%s\"" % os.path.join(remote_venv_export_path,"virtualenv","web","res","srvr_requirements.txt")) - -def do_sync_ldt(version, export_path): - print("do_sync_ldt with version %s and path %s" % (version,export_path)) - src_path = export_path + "/src/ldt" - build_src(src_path) - (_,version_str) = get_src_version(src_path) - build_path = os.path.join(src_path,"dist","ldt-%s.tar.gz" % version_str) - sync_install_build(build_path) - - -def sync_install_build(build_path): - res_trans = None - try: - res_trans = sync_build(build_path) - install_build(res_trans[0], env.remote_virtualenv_path) - finally: - if res_trans: - remove_build(res_trans[0]) - - -def do_sync_web(version, export_path): - print("do_sync_web with version %s and path %s" % (version,export_path)) - web_path = os.path.join(export_path,"web/") - rsync_export(web_path, env.remote_web_path, env.web_rsync_filters) - -def check_folder_access(): - print("Check folder access") - # get remote user - for folder_path in env.folders: - if not os.path.isabs(folder_path): - folder_path = env.remote_web_path.rstrip("/")+ "/" + folder_path - with settings(warn_only=True): - if not exists(folder_path): - run("mkdir -p \"%s\"" % folder_path) - run("chown -R -c :%s \"%s\"" % (env.web_group, folder_path)) - run("chmod -R -c g+w \"%s\"" % folder_path) -@task -def relaunch_server(do_collectstatic=True): - print("Relaunch server") - check_folder_access() - if do_collectstatic: - collectstatic(env.remote_web_path, env.remote_virtualenv_path, env.platform_web_module) - sudo(env.web_relaunch_cmd, shell=False) - -@task -def sync_web(version): - print(green("sync web with version %s" % version)) - export_path = export_version(version) - do_sync_web(version, export_path) - create_config(export_path) - clean_export_folder(export_path) - relaunch_server() - -@task -def sync_ldt(version): - print(green("sync ldt with version %s" % version)) - export_path = export_version(version) - do_sync_ldt(version, export_path) - clean_export_folder(export_path) - relaunch_server() - -@task -def update_lib(version, package): - print(green("update ldt with version %s" % version)) - export_path = export_version(version) - lib_path = os.path.join(export_path, "virtualenv", "res", "lib") - - f, pathname, description = imp.find_module("patch", [lib_path]) - patch = imp.load_module("patch", f, pathname, description) - f, pathname, description = imp.find_module("lib_create_env", [lib_path]) - lib_create_env = imp.load_module("lib_create_env", f, pathname, description) - - package_path = os.path.join(export_path, "virtualenv", "res", "src", lib_create_env.URLS[package]['local']) - - sync_install_build(package_path) - clean_export_folder(export_path) - relaunch_server() - -@task -def sync_platform(version): - print(green("sync platform with version %s" % version)) - export_path = export_version(version) - do_sync_ldt(version, export_path) - do_sync_web(version, export_path) - create_config(export_path) - clean_export_folder(export_path) - relaunch_server() - -@task -def create_virtualenv(version): - print(green("create virtualenv with version %s" % version)) - export_path = export_version(version) - venv_remote_export_path = "" - try: - virtualenv_path = os.path.join(export_path, "virtualenv") - - venv_remote_export_path = os.path.join(env.remote_venv_export_path, env.export_prefix, version,"virtualenv") - rsync_export(virtualenv_path, venv_remote_export_path, env.venv_rsync_filters) - do_create_virtualenv(venv_remote_export_path, env.remote_virtualenv_path) - finally: - clean_export_folder(export_path) - if venv_remote_export_path: - clean_rsync_folder(venv_remote_export_path) diff -r 9f7680957db8 -r 380d3657bc28 sbin/sync/sync_ldt_platform --- a/sbin/sync/sync_ldt_platform Fri Nov 30 11:59:47 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -#!/usr/bin/env bash -set -e -if [ -d ~/tmp/platform_V$1 ]; then - rm -fr ~/tmp/platform_V$1; -fi - -hg archive -r V$1 ~/tmp/platform_V$1 - -#text2unix ~/tmp/platform_V$1 - -if [ -d ~/tmp/platform_V$1 ]; then - cat < 0: + cleaned_data["src"] = src_prefix + "/" + base_source_filename + else: + cleaned_data["src"] = base_source_filename + + + 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 : ") + url) + elif media_input_type == "upload": + errors = media_form._errors.setdefault("media_file", ErrorList()) + errors.append(_("Problem when uploading file : ") + str(inst)) + finally: + if media_input_type == "url": + if destination_file: + destination_file.close() + if source_file: + source_file.close() + + + if form_status != "error": + del cleaned_data["media_file"] + if not cleaned_data['videopath']: + cleaned_data['videopath'] = settings.STREAM_URL + mimetype = cleaned_data.get('mimetype_field', None) + if not mimetype: + mimetype = mimetypes.guess_type(cleaned_data['src']) + cleaned_data['mimetype_field'] = mimetype + media, created = Media.safe_objects.get_or_create(src=cleaned_data['src'], defaults=cleaned_data) #@UndefinedVariable + cached_assign('view_media', request.user, media) + 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', 'front_project'): + setattr(media, attribute, cleaned_data.get(attribute)) + mimetype = cleaned_data.get('mimetype_field', None) + if not mimetype: + mimetype = mimetypes.guess_type(media.src) + media.mimetype_field = mimetype + cached_assign('view_media', request.user, media) + cached_assign('change_media', request.user, media) + media.save() + + return media, form_status + + @transaction.commit_manually def write_content_base(request, iri_id=None): if iri_id: @@ -48,7 +164,6 @@ if instance_content: current_front_project = instance_content.front_project form_status = 'none' - errors_transaction = [] if request.method == "POST": try: @@ -164,7 +279,7 @@ except Exception, e: transaction.rollback() __, value, traceback = sys.exc_info() - return False, False, False, False, False, errors_transaction, e, traceback + return False, False, False, False, False, e, traceback else: form_status = 'empty' @@ -192,18 +307,17 @@ transaction.commit() except Exception, e: transaction.rollback() - errors_transaction.append(e) - type, value, traceback = sys.exc_info() - return False, False, False, False, False, errors_transaction, e, traceback + __, __, traceback = sys.exc_info() + return False, False, False, False, False, e, traceback - return content_form, media_form, picture_form, form_status, current_front_project, errors_transaction, "", "" + return content_form, media_form, picture_form, form_status, current_front_project, "", "" @login_required def write_content(request, iri_id=None): submit_action = request.REQUEST.get("submit_button", False) member_list = admin_list = [] current_front_project = None - deleted = None + content_deleted = None if submit_action == "prepare_delete": errors, titles, message_temp = prepare_delete_content(request, iri_id) @@ -218,7 +332,7 @@ title_msg = _("confirm delete content") return render_to_response('ldt/ldt_utils/error_confirm.html', {'errors':errors, 'message':message, 'title': title_msg}, context_instance=RequestContext(request)) elif submit_action == "delete": - deleted, errors_transaction = delete_content(request, iri_id) + content_deleted, e, traceback = delete_content(request, iri_id) content_form = ContentForm() form_status = "deleted" elif submit_action == "prepare_reset": @@ -247,8 +361,8 @@ elif submit_action=="close": return redirect("root-view") else: - content_form, media_form, picture_form, form_status, current_front_project, errors_transaction, e, traceback = write_content_base(request, iri_id) - if iri_id: + content_form, media_form, picture_form, form_status, current_front_project, e, traceback = write_content_base(request, iri_id) + if iri_id: content_temp = Content.objects.get(iri_id=iri_id) media_temp = content_temp.media_obj if media_temp: @@ -256,11 +370,12 @@ else: member_list, admin_list = get_userlist_model(content_temp, request.user) - # Deleted is False if an error occurred during deletion - if (content_form == False and media_form == False and picture_form == False and form_status == False and current_front_project == False): - message=_("An error occurred - Please try again or contact webmaster") - title = _("Error") - logging.error(e) + if (content_form == False and media_form == False and picture_form == False and form_status == False and current_front_project == False): + message=_("An error occurred - Please try again or contact webmaster") + title = _("Error") + raise e, None, traceback + + if content_deleted == False: raise e, None, traceback if iri_id: @@ -287,126 +402,6 @@ 'elem_list':elem_list, 'member_list': member_list, 'admin_list': admin_list, 'iri_id': iri_id, 'session_key':session_key, 'cookie_name':cookie_name, 'img_container': img_container, 'profile_picture_form': picture_form, 'current_front_project':current_front_project}, context_instance=RequestContext(request)) - - -def media_management(request, media_input_type, cleaned_data, content_form, media_form, form_status): - if media_input_type == "none": - media = None - elif media_input_type == "link": - media = content_form.cleaned_data["media_obj"] - created = False - elif media_input_type == "create": - del cleaned_data["media_file"] - if not cleaned_data['videopath']: - cleaned_data['videopath'] = settings.STREAM_URL - # if the source is already http:// or rtmp:// we don't have to add STREAM_URL - 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" : - # copy file - #complet src - destination_file = None - source_file = None - try: - if media_input_type == "url": - url = cleaned_data["external_src_url"] - source_file = urllib2.urlopen(url) - source_filename = source_file.info().get('Content-Disposition', None) - 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'] - # 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) - 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 - - 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) - - elif media_input_type == "upload": - # The media file has been uploaded in the session temp folder - # so we just have to move to the regular folder and rename it. - if os.path.exists(os.path.join(settings.STREAM_PATH, "tmp/" + request.COOKIES[settings.SESSION_COOKIE_NAME] + "/", source_filename)): - os.rename(os.path.join(settings.STREAM_PATH, "tmp/" + request.COOKIES[settings.SESSION_COOKIE_NAME] + "/", source_filename), 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 - - - 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 : ") + url) - elif media_input_type == "upload": - errors = media_form._errors.setdefault("media_file", ErrorList()) - errors.append(_("Problem when uploading file : ") + str(inst)) - finally: - if media_input_type == "url": - if destination_file: - destination_file.close() - if source_file: - source_file.close() - - - if form_status != "error": - del cleaned_data["media_file"] - if not cleaned_data['videopath']: - cleaned_data['videopath'] = settings.STREAM_URL - mimetype = cleaned_data.get('mimetype_field', None) - if not mimetype: - mimetype = mimetypes.guess_type(cleaned_data['src']) - cleaned_data['mimetype_field'] = mimetype - media, created = Media.safe_objects.get_or_create(src=cleaned_data['src'], defaults=cleaned_data) #@UndefinedVariable - cached_assign('view_media', request.user, media) - 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', 'front_project'): - setattr(media, attribute, cleaned_data.get(attribute)) - mimetype = cleaned_data.get('mimetype_field', None) - if not mimetype: - mimetype = mimetypes.guess_type(media.src) - media.mimetype_field = mimetype - cached_assign('view_media', request.user, media) - cached_assign('change_media', request.user, media) - media.save() - - return media, form_status - - - @login_required def prepare_delete_content(request, iri_id=None): errors = [] @@ -451,20 +446,18 @@ except Exception, e: content.rollback() transaction.rollback() - errors_transaction.append(_("Content deletion failure")) - errors_transaction.append(e) - return False, errors_transaction + __, __, traceback = sys.exc_info() + return False, e, traceback else: try: transaction.commit() content.commit() - return True, errors_transaction - except: + return True, "", "" + except Exception, e: content.rollback() transaction.rollback() - errors_transaction.append(_("Commit of the content deletion failed")) - errors_transaction.append(e) - return False, errors_transaction + __, __, traceback = sys.exc_info() + return False, e, traceback def upload(request): if request.method == 'POST': diff -r 9f7680957db8 -r 380d3657bc28 src/ldt/ldt/static/ldt/metadataplayer/Annotation.css --- a/src/ldt/ldt/static/ldt/metadataplayer/Annotation.css Fri Nov 30 11:59:47 2012 +0100 +++ b/src/ldt/ldt/static/ldt/metadataplayer/Annotation.css Fri Nov 30 16:40:26 2012 +0100 @@ -6,6 +6,10 @@ margin: 0; } +.Ldt-Annotation-Highlight { + background: #ffa0fc; +} + .Ldt-Annotation-Widget.Ldt-Annotation-ShowTop { border-top-style: solid; padding-top: 1px; @@ -23,6 +27,11 @@ font-weight: bold; } +.Ldt-Annotation-Description { + max-height: 150px; + overflow: auto; +} + .Ldt-Annotation-Cleared { clear: both; } @@ -66,6 +75,7 @@ .Ldt-Annotation-Inner p { font-size: 12px; + line-height: 16px; } .Ldt-Annotation-Label { diff -r 9f7680957db8 -r 380d3657bc28 src/ldt/ldt/static/ldt/metadataplayer/Annotation.js --- a/src/ldt/ldt/static/ldt/metadataplayer/Annotation.js Fri Nov 30 11:59:47 2012 +0100 +++ b/src/ldt/ldt/static/ldt/metadataplayer/Annotation.js Fri Nov 30 16:40:26 2012 +0100 @@ -56,7 +56,8 @@ IriSP.Widgets.Annotation.prototype.draw = function() { - var _this = this; + var _this = this, + currentAnnotation; function timeupdate(_time) { var _list = _this.getWidgetAnnotationsAtTime(); @@ -70,13 +71,36 @@ } } + function highlightTitleAndDescription() { + if (!currentAnnotation) { + return; + } + var title = currentAnnotation.title, + description = currentAnnotation.description.replace(/(^\s+|\s+$)/g,''); + if (currentAnnotation.found) { + var rgxp = _this.source.getAnnotations().regexp || /^$/, + repl = '$1'; + title = title.replace(rgxp,repl); + description = description.replace(rgxp,repl).replace(/[\n\r]+/gm,'
'); + } + _this.$.find(".Ldt-Annotation-Title").html(title || "(" + _this.l10n.untitled + ")"); + if (description) { + _this.$.find(".Ldt-Annotation-Description-Block").removeClass("Ldt-Annotation-EmptyBlock"); + _this.$.find(".Ldt-Annotation-Description").html(description); + } else { + _this.$.find(".Ldt-Annotation-Description-Block").addClass("Ldt-Annotation-EmptyBlock"); + } + } + function drawAnnotation(_annotation) { + currentAnnotation = _annotation; var _url = (typeof _annotation.url !== "undefined" ? _annotation.url : (document.location.href.replace(/#.*$/,'') + '#id=' + _annotation.id)), _text = _this.l10n.watching + _annotation.title + (_this.site_name ? _this.l10n.on_site + _this.site_name : ''), _tags = _annotation.getTags(), _tagblock = _this.$.find(".Ldt-Annotation-Tags"); + _tagblock.empty(); if (_tags.length) { _this.$.find(".Ldt-Annotation-Tags-Block").removeClass("Ldt-Annotation-EmptyBlock"); _tags.forEach(function(_tag) { @@ -85,7 +109,7 @@ var _el = IriSP.jQuery('
  • ').append(IriSP.jQuery('').text(_trimmedTitle)); _el.click(function() { if (_this.search_on_tag_click) { - _this.player.trigger("search.triggeredSearch",_trimmedTitle); + _this.source.getAnnotations().search(_trimmedTitle); } _tag.trigger("click"); }); @@ -95,14 +119,7 @@ } else { _this.$.find(".Ldt-Annotation-Tags-Block").addClass("Ldt-Annotation-EmptyBlock"); } - _this.$.find(".Ldt-Annotation-Title").text(_annotation.title || "(" + _this.l10n.untitled + ")"); - var _desc = _annotation.description.replace(/(^\s+|\s+$)/g,''); - if (_desc) { - _this.$.find(".Ldt-Annotation-Description-Block").removeClass("Ldt-Annotation-EmptyBlock"); - _this.$.find(".Ldt-Annotation-Description").html(_desc); - } else { - _this.$.find(".Ldt-Annotation-Description-Block").addClass("Ldt-Annotation-EmptyBlock"); - } + highlightTitleAndDescription(); if (_this.show_annotation_type) { _this.$.find(".Ldt-Annotation-Type").text(_annotation.getAnnotationType().title) } @@ -135,7 +152,7 @@ this.renderTemplate(); - if (_this.show_social) { + if (this.show_social) { this.insertSubwidget(this.$.find(".Ldt-Annotation-Social"), { type: "Social" }, "socialWidget"); } @@ -152,6 +169,9 @@ drawAnnotation(_a) }); }); + this.source.getAnnotations().on("found", highlightTitleAndDescription); + this.source.getAnnotations().on("not-found", highlightTitleAndDescription); + this.source.getAnnotations().on("search-cleared", highlightTitleAndDescription); } IriSP.Widgets.Annotation.prototype.sendBounds = function() { diff -r 9f7680957db8 -r 380d3657bc28 src/ldt/ldt/static/ldt/metadataplayer/AnnotationsList.css --- a/src/ldt/ldt/static/ldt/metadataplayer/AnnotationsList.css Fri Nov 30 11:59:47 2012 +0100 +++ b/src/ldt/ldt/static/ldt/metadataplayer/AnnotationsList.css Fri Nov 30 16:40:26 2012 +0100 @@ -29,8 +29,7 @@ background-image: url(img/pinstripe-grey.png); } .Ldt-AnnotationsList-highlight { - background: #F7268E; - color: #ffffff; + background: #FFA0FC; } .Ldt-AnnotationsList-ThumbContainer { float: left; diff -r 9f7680957db8 -r 380d3657bc28 src/ldt/ldt/static/ldt/metadataplayer/AnnotationsList.js --- a/src/ldt/ldt/static/ldt/metadataplayer/AnnotationsList.js Fri Nov 30 11:59:47 2012 +0100 +++ b/src/ldt/ldt/static/ldt/metadataplayer/AnnotationsList.js Fri Nov 30 16:40:26 2012 +0100 @@ -1,11 +1,12 @@ IriSP.Widgets.AnnotationsList = function(player, config) { IriSP.Widgets.Widget.call(this, player, config); - this.searchString = false; this.lastIds = []; var _this = this; this.throttledRefresh = IriSP._.throttle(function() { _this.refresh(false); - }, 1500); + }, 800); + this.searchString = false; + this.lastSearch = false; }; IriSP.Widgets.AnnotationsList.prototype = new IriSP.Widgets.Widget(); @@ -87,18 +88,6 @@ + '{{#audio}}
    {{l10n.voice_annotation}}
    {{/audio}}' + ''; -IriSP.Widgets.AnnotationsList.prototype.onSearch = function(searchString) { - this.searchString = typeof searchString !== "undefined" ? searchString : ''; - var _n = this.refresh(true); - if (this.searchString) { - if (_n) { - this.player.trigger("search.matchFound"); - } else { - this.player.trigger("search.noMatchFound"); - } - } -} - //obj.url = this.project_url + "/" + media + "/" + annotations[i].meta.project + "/" + annotations[i].meta["id-ref"] + '#id=' + annotations[i].id; IriSP.Widgets.AnnotationsList.prototype.ajaxSource = function() { @@ -150,9 +139,9 @@ }); } } - if (this.searchString) { - _list = _list.searchByTextFields(this.searchString); - } + _list = _list.filter(function(_annotation) { + return _annotation.found !== false; + }); if (this.limit_count) { /* Get the n annotations closest to current timecode */ _list = _list.sortBy(function(_annotation) { @@ -171,8 +160,9 @@ var _ids = _list.idIndex; - if (_forceRedraw || !IriSP._.isEqual(_ids, this.lastIds)) { + if (_forceRedraw || !IriSP._.isEqual(_ids, this.lastIds) || this.searchString !== this.lastSearch) { /* This part only gets executed if the list needs updating */ + this.lastSearch = this.searchString; this.lastIds = _ids; this.list_$.html(""); _list.forEach(function(_annotation) { @@ -258,7 +248,7 @@ }); this.$.find('.Ldt-AnnotationsList-Tag-Li').click(function() { - _this.player.trigger("search.triggeredSearch", IriSP.jQuery(this).text().replace(/(^\s+|\s+$)/g,'')); + _this.source.getAnnotations().search(IriSP.jQuery(this).text().replace(/(^\s+|\s+$)/g,'')); }); this.$.find(".Ldt-AnnotationsList-Play").click(function() { @@ -274,11 +264,10 @@ _this.jw_paused_media = true; }); - if(this.searchString) { - var _searchRe = IriSP.Model.regexpFromTextOrArray(this.searchString); + if (this.source.getAnnotations().searching) { this.$.find(".Ldt-AnnotationsList-Title a, .Ldt-AnnotationsList-Description").each(function() { var _$ = IriSP.jQuery(this); - _$.html(_$.text().replace(/(^\s+|\s+$)/g,'').replace(_searchRe, '$1')) + _$.html(_$.text().replace(/(^\s+|\s+$)/g,'').replace(_this.source.getAnnotations().regexp, '$1')) }) } } @@ -328,9 +317,29 @@ this.list_$ = this.$.find(".Ldt-AnnotationsList-ul"); - this.onMdpEvent("search", "onSearch"); - this.onMdpEvent("search.closed", "onSearch"); - this.onMdpEvent("search.cleared", "onSearch"); + this.source.getAnnotations().on("search", function(_text) { + _this.searchString = _text; + if (_this.source !== _this.currentSource) { + _this.currentSource.getAnnotations().search(_text); + _this.throttledRefresh(); + } + }); + this.source.getAnnotations().on("found", function() { + _this.throttledRefresh(); + }); + this.source.getAnnotations().on("not-found", function() { + _this.throttledRefresh(); + }); + this.source.getAnnotations().on("clear-search", function() { + _this.searchString = false; + if (_this.source !== _this.currentSource) { + _this.currentSource.getAnnotations().trigger("clear-search"); + } + }); + this.source.getAnnotations().on("search-cleared", function() { + _this.throttledRefresh(); + }); + this.onMdpEvent("AnnotationsList.refresh", function() { if (_this.ajax_url) { if (_this.mashupMode) { diff -r 9f7680957db8 -r 380d3657bc28 src/ldt/ldt/static/ldt/metadataplayer/Controller.js --- a/src/ldt/ldt/static/ldt/metadataplayer/Controller.js Fri Nov 30 11:59:47 2012 +0100 +++ b/src/ldt/ldt/static/ldt/metadataplayer/Controller.js Fri Nov 30 16:40:26 2012 +0100 @@ -92,10 +92,6 @@ this.onMediaEvent("volumechange","volumeUpdater"); this.onMediaEvent("timeupdate","timeDisplayUpdater"); this.onMediaEvent("loadedmetadata","volumeUpdater"); - this.onMdpEvent("search.matchFound","searchMatch"); - this.onMdpEvent("search.noMatchFound","searchNoMatch"); - this.onMdpEvent("search.triggeredSearch","triggeredSearch"); - this.onMdpEvent("search.cleared","hideSearchBlock"); // handle clicks this.$playButton.click(this.functionWrapper("playHandler")); @@ -157,6 +153,21 @@ }); this.timeDisplayUpdater(new IriSP.Model.Time(0)); + + var annotations = this.source.getAnnotations(); + annotations.on("search", function(_text) { + _this.$searchInput.val(_text); + _this.showSearchBlock(); + }); + annotations.on("found", function(_text) { + _this.$searchInput.css('background-color','#e1ffe1'); + }); + annotations.on("not-found", function(_text) { + _this.$searchInput.css('background-color', "#d62e3a"); + }); + annotations.on("search-cleared", function() { + _this.hideSearchBlock(); + }); }; @@ -222,23 +233,11 @@ IriSP.Widgets.Controller.prototype.showSearchBlock = function() { this.$searchBlock.animate({ width:"160px" }, 200); this.$searchInput.css('background-color','#fff'); - this.$searchInput.focus(); - - // we need this variable because some widgets can find a match in - // their data while at the same time others don't. As we want the - // search field to become green when there's a match, we need a - // variable to remember that we had one. - this._positiveMatch = false; - - // tell the world the field is open - this.player.trigger("search.open"); }; IriSP.Widgets.Controller.prototype.hideSearchBlock = function() { this.$searchBlock.animate( { width: 0 }, 200); - this._positiveMatch = false; - this.player.trigger("search.closed"); }; /** react to clicks on the search button */ @@ -247,7 +246,7 @@ this.showSearchBlock(); var _val = this.$searchInput.val(); if (_val) { - this.player.trigger("search", _val); // trigger the search to make it more natural. + this.source.getAnnotations().search(_val); } } else { this.hideSearchBlock(); @@ -267,37 +266,12 @@ // do nothing if the search field is empty, instead of highlighting everything. if (_val !== this.lastSearchValue) { if (_val) { - this.player.trigger("search", _val); + this.source.getAnnotations().search(_val); } else { - this.player.trigger("search.cleared"); + this.source.getAnnotations().trigger("clear-search"); this.$searchInput.css('background-color',''); } } this.lastSearchValue = _val; }; -/** - handler for the IriSP.search.found message, which is sent by some views when they - highlight a match. -*/ -IriSP.Widgets.Controller.prototype.searchMatch = function() { - this._positiveMatch = true; - this.$searchInput.css('background-color','#e1ffe1'); -}; - -/** the same, except that no value could be found */ -IriSP.Widgets.Controller.prototype.searchNoMatch = function() { - if (this._positiveMatch !== true) { - this.$searchInput.css('background-color', "#d62e3a"); - } -}; - -/** react to an IriSP.Player.triggeredSearch - that is, when - a widget ask the.Player to do a search on his behalf */ -IriSP.Widgets.Controller.prototype.triggeredSearch = function(searchString) { - this.showSearchBlock(); - this.$searchInput.attr('value', searchString); - this.player.trigger("search", searchString); // trigger the search to make it more natural. -}; - - diff -r 9f7680957db8 -r 380d3657bc28 src/ldt/ldt/static/ldt/metadataplayer/KnowledgeConcierge.css --- a/src/ldt/ldt/static/ldt/metadataplayer/KnowledgeConcierge.css Fri Nov 30 11:59:47 2012 +0100 +++ b/src/ldt/ldt/static/ldt/metadataplayer/KnowledgeConcierge.css Fri Nov 30 16:40:26 2012 +0100 @@ -10,6 +10,32 @@ display: none; } +.Ldt-Kc-Related-Empty { + text-align: center; font-weight: bold; font-style: italic; + font-size: 14px; color: #999999; margin: 5px 0; +} + +.Ldt-Kc-Related h2 { + border: none; + color: #330099; + font-size: 18px; + margin: 8px 0 2px; + padding: 0 5px; +} + +h3.Ldt-Kc-For-Keywords { + border-bottom: 1px solid #666666; + color: #000000; + font-size: 12px; + margin: 2px 0 5px; + padding: 0 5px 5px; + text-align: right; +} + +.Ldt-Kc-Keywords { + color: #d000c0; font-weight: bold; +} + .Ldt-Kc-Related-Item { width: 235px; float: left; margin: 4px 0; padding: 4px 0; } @@ -30,7 +56,7 @@ max-width: 80px; max-height: 60px; float: left; } -.Ldt-Kc-Related-Item h3, p { +.Ldt-Kc-Related-Item h3, .Ldt-Kc-Related-Item p { margin: 0 0 5px 85px; } diff -r 9f7680957db8 -r 380d3657bc28 src/ldt/ldt/static/ldt/metadataplayer/KnowledgeConcierge.js --- a/src/ldt/ldt/static/ldt/metadataplayer/KnowledgeConcierge.js Fri Nov 30 11:59:47 2012 +0100 +++ b/src/ldt/ldt/static/ldt/metadataplayer/KnowledgeConcierge.js Fri Nov 30 16:40:26 2012 +0100 @@ -13,24 +13,29 @@ related_api_endpoint: "", use_word_boundaries: false, related_data_type: 'json', // SET TO "jsonp" FOR CROSS-DOMAIN OPERATION - related_count: 8 + related_count: 8, } IriSP.Widgets.KnowledgeConcierge.prototype.messages = { "fr": { related_videos: "Vidéos liées", - duration_: "Durée :" + duration_: "Durée :", + for_keywords_: "pour le(s) mots-clé(s) :", + no_matching_videos: "Pas de vidéos correspondantes" }, "en": { related_videos: "Related Videos", - duration_: "Duration:" + duration_: "Duration:", + for_keywords_: "for keyword(s):", + no_matching_videos: "No matching videos" } } IriSP.Widgets.KnowledgeConcierge.prototype.template = '
    ' + + '