# HG changeset patch # User rougeronj # Date 1349885260 -7200 # Node ID 7f237270b61cacf04e8852aa8268827780ae5d68 # Parent e5b5e9d56eece63b6e22d2c77aacb2238f5fb985# Parent b38c88bdefa2b95fd3817872131694960f5468a0 Merge with b38c88bdefa2b95fd3817872131694960f5468a0 diff -r e5b5e9d56eec -r 7f237270b61c .settings/org.eclipse.core.resources.prefs --- a/.settings/org.eclipse.core.resources.prefs Wed Oct 10 17:55:18 2012 +0200 +++ b/.settings/org.eclipse.core.resources.prefs Wed Oct 10 18:07:40 2012 +0200 @@ -1,43 +1,43 @@ -#Fri Sep 28 10:36:06 CEST 2012 -eclipse.preferences.version=1 -encoding//src/ldt/ldt/core/migrations/0001_initial.py=utf-8 -encoding//src/ldt/ldt/core/migrations/0002_auto__del_owner.py=utf-8 -encoding//src/ldt/ldt/indexation/backends/elasticsearch_backend.py=utf-8 -encoding//src/ldt/ldt/indexation/highlighter.py=utf-8 -encoding//src/ldt/ldt/indexation/models.py=utf-8 -encoding//src/ldt/ldt/indexation/query_parser.py=utf-8 -encoding//src/ldt/ldt/indexation/search_indexes.py=utf-8 -encoding//src/ldt/ldt/indexation/tests.py=utf-8 -encoding//src/ldt/ldt/ldt_utils/migrations/0001_initial.py=utf-8 -encoding//src/ldt/ldt/ldt_utils/migrations/0002_auto__add_field_media_mimetype_field__chg_field_media_external_src_url.py=utf-8 -encoding//src/ldt/ldt/ldt_utils/migrations/0003_auto__chg_field_project_owner.py=utf-8 -encoding//src/ldt/ldt/ldt_utils/migrations/0004_auto__add_field_project_description.py=utf-8 -encoding//src/ldt/ldt/ldt_utils/migrations/0005_add_permissions.py=utf-8 -encoding//src/ldt/ldt/ldt_utils/migrations/0006_auto__add_field_media_image.py=utf-8 -encoding//src/ldt/ldt/ldt_utils/migrations/0007_auto__add_field_content_image__del_field_media_image.py=utf-8 -encoding//src/ldt/ldt/ldt_utils/migrations/0008_auto__add_field_project_image.py=utf-8 -encoding//src/ldt/ldt/ldt_utils/migrations/0009_auto__chg_field_content_image__chg_field_project_image.py=utf-8 -encoding//src/ldt/ldt/ldt_utils/migrations/0010_auto__add_annotationstat.py=utf-8 -encoding//src/ldt/ldt/ldt_utils/migrations/0011_gen_stat_annotation.py=utf-8 -encoding//src/ldt/ldt/ldt_utils/migrations/0012_auto__add_field_content_last_annotated.py=utf-8 -encoding//src/ldt/ldt/ldt_utils/migrations/0013_auto__add_field_content_front_project__chg_field_content_last_annotate.py=utf-8 -encoding//src/ldt/ldt/ldt_utils/migrations/0014_auto__del_annotationstat__chg_field_content_last_annotated.py=utf-8 -encoding//src/ldt/ldt/ldt_utils/migrations/0015_auto__add_contentstat__del_field_content_last_annotated__del_field_con.py=utf-8 -encoding//src/ldt/ldt/ldt_utils/migrations/0016_one_to_one_stat_annotation.py=utf-8 -encoding//src/ldt/ldt/ldt_utils/migrations/0017_correct_image_path.py=utf-8 -encoding//src/ldt/ldt/ldt_utils/migrations/0018_auto__chg_field_content_iri_id__chg_field_project_ldt_id__chg_field_au.py=utf-8 -encoding//src/ldt/ldt/ldt_utils/migrations/0019_recalculate_media_hash_src.py=utf-8 -encoding//src/ldt/ldt/ldt_utils/migrations/0020_auto__add_field_segment_id_hash__chg_field_segment_iri_id__chg_field_s.py=utf-8 -encoding//src/ldt/ldt/ldt_utils/migrations/0021_recalculate_segment_id_hash_script.py=utf-8 -encoding//src/ldt/ldt/ldt_utils/migrations/0022_auto__add_unique_media_src_hash__chg_field_segment_cutting_id__chg_fie.py=utf-8 -encoding//src/ldt/ldt/ldt_utils/migrations/0023_auto__add_field_segment_audio_src__add_field_segment_audio_href.py=utf-8 -encoding//src/ldt/ldt/ldt_utils/views/json.py=utf-8 -encoding//src/ldt/ldt/management/utils.py=utf-8 -encoding//src/ldt/ldt/test/test_runner.py=utf-8 -encoding//src/ldt/ldt/text/migrations/0001_initial.py=utf-8 -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 +eclipse.preferences.version=1 +encoding//src/ldt/ldt/core/migrations/0001_initial.py=utf-8 +encoding//src/ldt/ldt/core/migrations/0002_auto__del_owner.py=utf-8 +encoding//src/ldt/ldt/indexation/backends/elasticsearch_backend.py=utf-8 +encoding//src/ldt/ldt/indexation/highlighter.py=utf-8 +encoding//src/ldt/ldt/indexation/models.py=utf-8 +encoding//src/ldt/ldt/indexation/query_parser.py=utf-8 +encoding//src/ldt/ldt/indexation/search_indexes.py=utf-8 +encoding//src/ldt/ldt/indexation/tests.py=utf-8 +encoding//src/ldt/ldt/ldt_utils/migrations/0001_initial.py=utf-8 +encoding//src/ldt/ldt/ldt_utils/migrations/0002_auto__add_field_media_mimetype_field__chg_field_media_external_src_url.py=utf-8 +encoding//src/ldt/ldt/ldt_utils/migrations/0003_auto__chg_field_project_owner.py=utf-8 +encoding//src/ldt/ldt/ldt_utils/migrations/0004_auto__add_field_project_description.py=utf-8 +encoding//src/ldt/ldt/ldt_utils/migrations/0005_add_permissions.py=utf-8 +encoding//src/ldt/ldt/ldt_utils/migrations/0006_auto__add_field_media_image.py=utf-8 +encoding//src/ldt/ldt/ldt_utils/migrations/0007_auto__add_field_content_image__del_field_media_image.py=utf-8 +encoding//src/ldt/ldt/ldt_utils/migrations/0008_auto__add_field_project_image.py=utf-8 +encoding//src/ldt/ldt/ldt_utils/migrations/0009_auto__chg_field_content_image__chg_field_project_image.py=utf-8 +encoding//src/ldt/ldt/ldt_utils/migrations/0010_auto__add_annotationstat.py=utf-8 +encoding//src/ldt/ldt/ldt_utils/migrations/0011_gen_stat_annotation.py=utf-8 +encoding//src/ldt/ldt/ldt_utils/migrations/0012_auto__add_field_content_last_annotated.py=utf-8 +encoding//src/ldt/ldt/ldt_utils/migrations/0013_auto__add_field_content_front_project__chg_field_content_last_annotate.py=utf-8 +encoding//src/ldt/ldt/ldt_utils/migrations/0014_auto__del_annotationstat__chg_field_content_last_annotated.py=utf-8 +encoding//src/ldt/ldt/ldt_utils/migrations/0015_auto__add_contentstat__del_field_content_last_annotated__del_field_con.py=utf-8 +encoding//src/ldt/ldt/ldt_utils/migrations/0016_one_to_one_stat_annotation.py=utf-8 +encoding//src/ldt/ldt/ldt_utils/migrations/0017_correct_image_path.py=utf-8 +encoding//src/ldt/ldt/ldt_utils/migrations/0018_auto__chg_field_content_iri_id__chg_field_project_ldt_id__chg_field_au.py=utf-8 +encoding//src/ldt/ldt/ldt_utils/migrations/0019_recalculate_media_hash_src.py=utf-8 +encoding//src/ldt/ldt/ldt_utils/migrations/0020_auto__add_field_segment_id_hash__chg_field_segment_iri_id__chg_field_s.py=utf-8 +encoding//src/ldt/ldt/ldt_utils/migrations/0021_recalculate_segment_id_hash_script.py=utf-8 +encoding//src/ldt/ldt/ldt_utils/migrations/0022_auto__add_unique_media_src_hash__chg_field_segment_cutting_id__chg_fie.py=utf-8 +encoding//src/ldt/ldt/ldt_utils/migrations/0023_auto__add_field_segment_audio_src__add_field_segment_audio_href.py=utf-8 +encoding//src/ldt/ldt/ldt_utils/views/json.py=utf-8 +encoding//src/ldt/ldt/management/utils.py=utf-8 +encoding//src/ldt/ldt/test/test_runner.py=utf-8 +encoding//src/ldt/ldt/text/migrations/0001_initial.py=utf-8 +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 e5b5e9d56eec -r 7f237270b61c src/ldt/ldt/ldt_utils/models.py --- a/src/ldt/ldt/ldt_utils/models.py Wed Oct 10 17:55:18 2012 +0200 +++ b/src/ldt/ldt/ldt_utils/models.py Wed Oct 10 18:07:40 2012 +0200 @@ -1,6 +1,7 @@ from django.conf import settings from django.contrib.auth.models import User, Group from django.db import models +from django.db import transaction from django.utils.translation import ugettext_lazy as _ from guardian.shortcuts import assign, remove_perm, get_perms from ldt.core.models import Document @@ -20,6 +21,9 @@ import re import tagging.fields import uuid +import logging +from shutil import rmtree, move +from django.core.files.storage import default_storage #from ldt.core.models import Document, Owner @@ -170,6 +174,55 @@ if not hasattr(Content, 'pol_positive'): self.__add_polemic_attributes() + + def delete(self): + super(Content, self).delete() + iri_file_path = self.iri_file_path() + thumbnail = os.path.join(settings.MEDIA_ROOT, unicode(self.image)) + if os.path.exists(iri_file_path): + dir = os.path.dirname(iri_file_path) + temp = os.path.join(os.path.join(os.path.dirname(dir), "temp"), self.iri_id) + try: + move(dir, temp) + except Exception, e: + raise e + if os.path.exists(thumbnail): + if os.path.basename(thumbnail) != os.path.basename(settings.DEFAULT_CONTENT_ICON): + temp_thumbnail = os.path.join(os.path.dirname(thumbnail), "temp") + try: + if not os.path.exists(temp_thumbnail): + os.makedirs(temp_thumbnail) + move(thumbnail, os.path.join(temp_thumbnail, os.path.basename(thumbnail))) + except Exception, e: + raise e + + #del .iri, and .png from temp directory + def commit(self): + iri_file_path=self.iri_file_path() + dir = os.path.dirname(iri_file_path) + temp = os.path.join(os.path.join(os.path.dirname(dir), "temp"), self.iri_id) + thumbnail = os.path.join(settings.MEDIA_ROOT, unicode(self.image)) + temp_thumbnail = os.path.join(os.path.dirname(thumbnail), "temp") + if os.path.exists(temp): + default_storage.delete(os.path.join(temp, os.path.basename(self.iriurl))) + os.rmdir(temp) + if os.path.exists(temp_thumbnail): + default_storage.delete(os.path.join(temp_thumbnail, os.path.basename(thumbnail))) + os.rmdir(temp_thumbnail) + + #move .iri, and .png to there original directory + def rollback(self): + iri_file_path=self.iri_file_path() + dir = os.path.dirname(iri_file_path) + temp = os.path.join(os.path.join(os.path.dirname(dir), "temp"), self.iri_id) + thumbnail = os.path.join(settings.MEDIA_ROOT, unicode(self.image)) + temp_thumbnail = os.path.join(os.path.dirname(thumbnail), "temp") + if os.path.exists(temp): + move(temp, dir) + os.rmdir(os.path.dirname(temp)) + if os.path.exists(temp_thumbnail): + move(os.path.join(temp_thumbnail, os.path.basename(thumbnail)), os.path.dirname(thumbnail)) + os.rmdir(temp_thumbnail) def natural_key(self): return self.iri_id @@ -230,8 +283,6 @@ def save(self, *args, **kwargs): create_front_project = False - # update it - self.sync_iri_file() if not self.pk: create_front_project = True @@ -244,6 +295,10 @@ # save() has to be called first self.create_front_project() assign('ldt_utils.change_content', get_current_user(), self) + + # update it + # To put after project creation, to assume transaction + self.sync_iri_file() def __unicode__(self): @@ -662,6 +717,17 @@ else: return False + def has_annotations(self): + nb_annot = 0 + doc = lxml.etree.fromstring(self.ldt) + res = doc.xpath("/iri/annotations/content/ensemble/decoupage") + for r in res: + nb_annot = nb_annot + r.find('elements').__len__() + if nb_annot == 0: + return False + else: + return True + def ldt_encoded(): #@NoSelf def fget(self): @@ -743,6 +809,3 @@ permissions = ( ('view_segment', 'Can view segment'), ) - - - diff -r e5b5e9d56eec -r 7f237270b61c src/ldt/ldt/ldt_utils/views/content.py --- a/src/ldt/ldt/ldt_utils/views/content.py Wed Oct 10 17:55:18 2012 +0200 +++ b/src/ldt/ldt/ldt_utils/views/content.py Wed Oct 10 18:07:40 2012 +0200 @@ -4,6 +4,7 @@ from django.core.urlresolvers import reverse from django.forms.models import model_to_dict from django.core.files import File +from django.db import transaction #from django.core.files.temp import NamedTemporaryFile from django.forms.util import ErrorList from django.http import HttpResponse, HttpResponseRedirect @@ -29,8 +30,9 @@ import requests import django.utils.simplejson as simplejson import urlparse -import tempfile +import tempfile +@transaction.commit_manually def write_content_base(request, iri_id=None): if iri_id: instance_content = Content.safe_objects.get(iri_id=iri_id) #@UndefinedVariable @@ -44,282 +46,309 @@ if instance_content: current_front_project = instance_content.front_project form_status = 'none' - if request.method == "POST": - - if instance_content is not None: - content_instance_val = model_to_dict(instance_content, exclude=ContentForm.Meta.exclude) - else: - content_instance_val = {} - - if instance_media is not None: - media_instance_val = model_to_dict(instance_media, exclude=MediaForm.Meta.exclude) - else: - media_instance_val = {} - #add prefix - - def add_prefix(_dict, prefix): - return dict([('%s-%s' % (prefix, key), value) for key,value in _dict.items()]) - - content_instance_val = add_prefix(content_instance_val, "content") - media_instance_val= add_prefix(media_instance_val, "media") - - for k in request.POST.keys(): - value = request.POST.get(k) - content_instance_val[k] = value - media_instance_val[k] = value + errors_transaction = [] + + # catch error from creating content, project, media + try: + if request.method == "POST": + + if instance_content is not None: + content_instance_val = model_to_dict(instance_content, exclude=ContentForm.Meta.exclude) + else: + content_instance_val = {} - content_instance_val['read_list'] = request.POST.getlist('read_list') - content_instance_val['write_list'] = request.POST.getlist('write_list') - content_instance_val['share'] = request.POST.get('share', True) - - content_form = ContentForm(content_instance_val, prefix="content", instance=instance_content) - media_form = MediaForm(media_instance_val, request.FILES, prefix="media", instance=instance_media) - picture_form = PictureForm(None, request.POST, request.FILES) - - if request.user.is_staff: - content_form.fields['front_project'].queryset = Project.objects.filter(contents__in=[instance_content]) - - - media_valid = media_form.is_valid() - content_valid = content_form.is_valid() - picture_valid = picture_form.is_valid() - if 'image' in request.POST.keys(): - image_link = request.POST.get('url_image') - if picture_valid and image_link!='' : - try : - r = requests.get(image_link) - img_temp = tempfile.NamedTemporaryFile(suffix='.png') - if img_temp: - img_temp.write(r.content) - img_temp.flush() - picture_form.cleaned_data["image"]=File(img_temp) - except Exception as inst: - logging.debug("couldn't download video thumbnail from image_link : "+str(image_link)) - logging.debug("write_content_base : valid form: for instance : " + repr(instance_media) + " -> media " + str(media_valid) + " content : for instance : " + repr(instance_content) + " : " + str(content_valid) + "picture : valid :" +str(picture_valid)+" loulou") #@UndefinedVariable - - if media_valid and content_valid and picture_valid: - - # see if media must be created - cleaned_data = {} - cleaned_data.update(media_form.cleaned_data) - cleaned_data.pop("media_public") + if instance_media is not None: + media_instance_val = model_to_dict(instance_media, exclude=MediaForm.Meta.exclude) + else: + media_instance_val = {} + #add prefix + + def add_prefix(_dict, prefix): + return dict([('%s-%s' % (prefix, key), value) for key,value in _dict.items()]) - media_input_type = content_form.cleaned_data["media_input_type"] + content_instance_val = add_prefix(content_instance_val, "content") + media_instance_val= add_prefix(media_instance_val, "media") + + for k in request.POST.keys(): + value = request.POST.get(k) + content_instance_val[k] = value + media_instance_val[k] = value + + content_instance_val['read_list'] = request.POST.getlist('read_list') + content_instance_val['write_list'] = request.POST.getlist('write_list') + content_instance_val['share'] = request.POST.get('share', True) - 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() + content_form = ContentForm(content_instance_val, prefix="content", instance=instance_content) + media_form = MediaForm(media_instance_val, request.FILES, prefix="media", instance=instance_media) + picture_form = PictureForm(None, request.POST, request.FILES) + + if request.user.is_staff: + content_form.fields['front_project'].queryset = Project.objects.filter(contents__in=[instance_content]) + + + media_valid = media_form.is_valid() + content_valid = content_form.is_valid() + picture_valid = picture_form.is_valid() + if 'image' in request.POST.keys(): + image_link = request.POST.get('url_image') + if picture_valid and image_link!='' : + try : + r = requests.get(image_link) + img_temp = tempfile.NamedTemporaryFile(suffix='.png') + if img_temp: + img_temp.write(r.content) + img_temp.flush() + picture_form.cleaned_data["image"]=File(img_temp) + except Exception as inst: + logging.debug("couldn't download video thumbnail from image_link : "+str(image_link)) + logging.debug("write_content_base : valid form: for instance : " + repr(instance_media) + " -> media " + str(media_valid) + " content : for instance : " + repr(instance_content) + " : " + str(content_valid) + "picture : valid :" +str(picture_valid)+" loulou") #@UndefinedVariable + + if media_valid and content_valid and picture_valid: + + # see if media must be created + cleaned_data = {} + cleaned_data.update(media_form.cleaned_data) + cleaned_data.pop("media_public") + media_input_type = content_form.cleaned_data["media_input_type"] - if form_status != "error": - #try: + 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": + #try: + 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(cleaned_data['src']) - cleaned_data['mimetype_field'] = mimetype - media, created = Media.safe_objects.get_or_create(src=cleaned_data['src'], defaults=cleaned_data) #@UndefinedVariable + mimetype = mimetypes.guess_type(media.src) + media.mimetype_field = mimetype 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() - - if form_status != "error": - content_defaults = {} - content_defaults.update(content_form.cleaned_data) - content_defaults['media_obj'] = media - - for key in ["media_input_type", "groups", "is_public", "read_list", "write_list", "share" ]: - del content_defaults[key] - - content, created = Content.safe_objects.get_or_create(iri_id=content_form.cleaned_data['iri_id'], defaults=content_defaults) #@UndefinedVariable - - if not created and not request.user.has_perm('ldt_utils.change_content', content): - raise AttributeError("%s is not allowed to change content %s" % (request.user, content)) - - cached_assign('change_content', request.user, content) - cached_assign('view_content', request.user, content) - everyone = Group.objects.get(name=settings.PUBLIC_GROUP_NAME) + cached_assign('change_media', request.user, media) + media.save() - if media_form.cleaned_data['media_public']: - cached_assign('view_content', everyone, content) - if media: - cached_assign('view_media', everyone, media) - else: - remove_perm('ldt_utils.view_media', everyone, media) - if media: - assign_perm_to_obj(media, content_form.cleaned_data['read_list'], content_form.cleaned_data['write_list'], request.user) - assign_perm_to_obj(content, content_form.cleaned_data['read_list'], content_form.cleaned_data['write_list'], request.user) - if content_form.cleaned_data['is_public']: + if form_status != "error": + content_defaults = {} + content_defaults.update(content_form.cleaned_data) + content_defaults['media_obj'] = media + + for key in ["media_input_type", "groups", "is_public", "read_list", "write_list", "share" ]: + del content_defaults[key] + + content, created = Content.safe_objects.get_or_create(iri_id=content_form.cleaned_data['iri_id'], defaults=content_defaults) #@UndefinedVariable + + if not created and not request.user.has_perm('ldt_utils.change_content', content): + raise AttributeError("%s is not allowed to change content %s" % (request.user, content)) + + cached_assign('change_content', request.user, content) + cached_assign('view_content', request.user, content) + everyone = Group.objects.get(name=settings.PUBLIC_GROUP_NAME) + + if media_form.cleaned_data['media_public']: cached_assign('view_content', everyone, content) + if media: + cached_assign('view_media', everyone, media) else: - remove_perm('ldt_utils.view_content', everyone, content) - - if not created: - for attribute in ('iriurl', 'title', 'description', 'duration', 'content_creation_date', 'tags', 'media_obj'): - setattr(content, attribute, content_defaults[attribute]) - - if request.user.is_staff and content_defaults.has_key('front_project'): - content.front_project = content_defaults['front_project'] + remove_perm('ldt_utils.view_media', everyone, media) + if media: + assign_perm_to_obj(media, content_form.cleaned_data['read_list'], content_form.cleaned_data['write_list'], request.user) + assign_perm_to_obj(content, content_form.cleaned_data['read_list'], content_form.cleaned_data['write_list'], request.user) + if content_form.cleaned_data['is_public']: + cached_assign('view_content', everyone, content) + else: + remove_perm('ldt_utils.view_content', everyone, content) - content.save() - picture_form.model = content - picture_form.save() - form_status = 'saved' - media_form = MediaForm(instance=media, prefix="media") - content_form = ContentForm(instance=content, prefix="content") - picture_form = PictureForm() - else: - form_status = 'error' - else: - form_status = 'empty' - initial_c = { 'media_input_type':"link"} - initial_m = {} - if instance_media: - initial_m['media_public'] = instance_media.is_public + if not created: + for attribute in ('iriurl', 'title', 'description', 'duration', 'content_creation_date', 'tags', 'media_obj'): + setattr(content, attribute, content_defaults[attribute]) + + if request.user.is_staff and content_defaults.has_key('front_project'): + content.front_project = content_defaults['front_project'] + + content.save() + picture_form.model = content + picture_form.save() + form_status = 'saved' + media_form = MediaForm(instance=media, prefix="media") + content_form = ContentForm(instance=content, prefix="content") + picture_form = PictureForm() + else: + form_status = 'error' else: - initial_m['media_public'] = True - if instance_content: - initial_c['is_public'] = instance_content.is_public - else: - initial_c['is_public'] = True - content_form = ContentForm(prefix="content", instance=instance_content, initial=initial_c) - media_form = MediaForm(prefix="media", instance=instance_media, initial=initial_m) - picture_form = PictureForm() - - if instance_content is not None: - content_form.media_input_type = "link" - - if request.user.is_staff: - content_form.fields['front_project'].queryset = Project.objects.filter(contents__in=[instance_content]) - - return content_form, media_form, picture_form, form_status, current_front_project + form_status = 'empty' + initial_c = { 'media_input_type':"link"} + initial_m = {} + if instance_media: + initial_m['media_public'] = instance_media.is_public + else: + initial_m['media_public'] = True + if instance_content: + initial_c['is_public'] = instance_content.is_public + else: + initial_c['is_public'] = True + content_form = ContentForm(prefix="content", instance=instance_content, initial=initial_c) + media_form = MediaForm(prefix="media", instance=instance_media, initial=initial_m) + picture_form = PictureForm() + + if instance_content is not None: + content_form.media_input_type = "link" + + if request.user.is_staff: + content_form.fields['front_project'].queryset = Project.objects.filter(contents__in=[instance_content]) + except: + transaction.rollback() + errors_transaction.append(_("Content creation failure")) + return False, False, False, False, False, errors_transaction + else: + #Try to make sure the commit succeeded or not. + try: + transaction.commit() + except: + transaction.rollback() + errors_transaction.append(_("Commit of the content creation failed")) + return False, False, False, False, False, errors_transaction + return content_form, media_form, picture_form, form_status, current_front_project, errors_transaction @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 - if submit_action == "prepare_delete": - errors, titles = prepare_delete_content(request, iri_id) - if errors and len(errors) > 0: - message = ungettext("There is %(count)d error when deleting content", "There are %(count)d errors when deleting content", len(errors)) % { 'count': len(errors)} - title_msg = _('title error deleting content') + if submit_action == "prepare_delete": + errors, titles, delete, message_temp = prepare_delete_content(request, iri_id) + #if there is only front_project, with no annotations, delete without confirmation + if delete: + deleted, errors_transaction = delete_content(request, iri_id) + content_form = ContentForm() + form_status="deleted" else: - message = _("Confirm delete content %(titles)s") % { 'titles' : ",".join(titles) } - 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)) + if errors and len(errors) > 0: + message = ungettext("There is %(count)d error when deleting content", "There are %(count)d errors when deleting content", len(errors)) % { 'count': len(errors)} + title_msg = _('title error deleting content') + else: + if len(message_temp)>0: + message = message_temp + else: + message = _("Confirm delete content %(titles)s") % { 'titles' : ",".join(titles) } + 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": - delete_content(request, iri_id) + deleted, errors_transaction = delete_content(request, iri_id) + content_form = contentForm() form_status = "deleted" - content_form = ContentForm() - media_form = MediaForm() - picture_form = PictureForm() elif submit_action == "prepare_reset": errors=[] content_temp = Content.objects.get(iri_id=iri_id) - if content_temp.front_project.state==2: - errors.append(_("Please unpublish the front project %(title)s") % {'title':content_temp.front_project.title}) - message=_("The front project is published") - title = _("confirm reset") + if content_temp.front_project is not None: + if content_temp.front_project.state==2: + errors.append(_("Please unpublish the front project %(title)s") % {'title':content_temp.front_project.title}) + message=_("The front project is published") + title = _("confirm reset") + else: + message = _("please confirm reseting project %(title)s") % {'title':content_temp.front_project.title} + title = _("confirm reset") else: - message = _("please confirm reseting project %(title)s") % {'title':content_temp.front_project.title} - title = _("confirm reset") + content_temp.create_front_project() + return redirect("root-view") return render_to_response('ldt/ldt_utils/reset_confirm.html', {'errors':errors, 'message':message, 'title': title}, context_instance=RequestContext(request)) elif submit_action == "reset": #TODO : verifier index de la recherche maj @@ -328,12 +357,11 @@ content.create_front_project() content.save() project_temp.delete() - form_status= 'saved' return HttpResponseRedirect(reverse('ldt.ldt_utils.views.content.write_content', kwargs={'iri_id':iri_id})) elif submit_action=="close": return redirect("root-view") else: - content_form, media_form, picture_form, form_status, current_front_project = write_content_base(request, iri_id) + content_form, media_form, picture_form, form_status, current_front_project, errors_transaction = write_content_base(request, iri_id) if iri_id: content_temp = Content.objects.get(iri_id=iri_id) media_temp = content_temp.media_obj @@ -341,6 +369,13 @@ member_list, admin_list = get_userlist_model(media_temp, request.user) else: member_list, admin_list = get_userlist_model(content_temp, request.user) + + # Deleted is False if an error occurred during deletion + if (deleted == False) or (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") + return render_to_response('ldt/ldt_utils/error_confirm.html', {'errors':errors_transaction, 'message':message, 'title': title}, context_instance=RequestContext(request)) + if iri_id: create_content_action = reverse('ldt.ldt_utils.views.content.write_content', kwargs={'iri_id':iri_id}) img_container = content_form.instance @@ -369,6 +404,8 @@ def prepare_delete_content(request, iri_id=None): errors = [] titles = [] + delete = False + message={} if not iri_id: iri_id = request.REQUEST.get("iri_id", None) @@ -377,21 +414,53 @@ titles.append(unicode(content.title)) projects = content.project_set.all() projects_nb = len(projects) - if projects_nb > 0: + if projects_nb > 1: project_titles = map(lambda p: unicode(p.title), projects) errors.append(ungettext("Content '%(title)s' is referenced by this project : %(project_titles)s. Please delete it beforehand.", "Content '%(title)s' is referenced by %(count)d projects: %(project_titles)s. Please delete them beforehand.", projects_nb) % {'title':unicode(content.title), 'count':projects_nb, 'project_titles': ",".join(project_titles)}) - - return errors, titles + elif projects_nb == 1: + if not projects[0].has_annotations(): + delete = True + else: + message = _("The project '%(project_title)s' pointing on the content '%(title)s' has several annotations. Do you want to delete the content and the project anyway ?")% {'project_title':unicode(projects[0].title), 'title':unicode(content.title)} + elif project_nb == 0: + delete = True + return errors, titles, delete, message @login_required +@transaction.commit_manually def delete_content(request, iri_id=None): + #Delete the project, the media if exists, and the content + errors_transaction=[] if not iri_id: - iri_id = request.REQUEST.get("iri_id", None) - + iri_id = request.REQUEST.get("iri_id", None) if iri_id: - Content.safe_objects.get(iri_id=iri_id).delete() - + content = Content.safe_objects.get(iri_id=iri_id) + try: + if content.media_obj is not None: + contents_media = Content.safe_objects.filter(media_obj = content.media_obj) + #check if the media is ref by severals content + if len(contents_media) < 2: + Media.safe_objects.get(id=content.media_obj.id).delete() + project = content.front_project + content.delete() + if project is not None: + Project.safe_objects.get(ldt_id= project.ldt_id).delete() + except: + content.rollback() + transaction.rollback() + errors_transaction.append(_("Content deletion failure")) + return False, errors_transaction + else: + try: + transaction.commit() + content.commit() + return True, errors_transaction + except: + transaction.rollback() + content.rollback() + errors_transaction.append(_("Commit of the content deletion failed")) + return False, errors_transaction def upload(request): if request.method == 'POST': diff -r e5b5e9d56eec -r 7f237270b61c src/ldt/ldt/locale/fr/LC_MESSAGES/django.mo Binary file src/ldt/ldt/locale/fr/LC_MESSAGES/django.mo has changed diff -r e5b5e9d56eec -r 7f237270b61c src/ldt/ldt/locale/fr/LC_MESSAGES/django.po --- a/src/ldt/ldt/locale/fr/LC_MESSAGES/django.po Wed Oct 10 17:55:18 2012 +0200 +++ b/src/ldt/ldt/locale/fr/LC_MESSAGES/django.po Wed Oct 10 18:07:40 2012 +0200 @@ -18,7 +18,7 @@ #: .\forms\fields.py:17 msgid "Enter a valid duration format" -msgstr "" +msgstr "Entrez un format de durée valide" #: .\forms\widgets.py:21 msgid "Date" @@ -931,54 +931,71 @@ msgid "Project published" msgstr "Projet publié" -#: .\ldt_utils\views\content.py:183 +#: .\ldt_utils\views\content.py:189 msgid "Problem when downloading file from url : " msgstr "Problème lors du téléchargement du fichier : " -#: .\ldt_utils\views\content.py:186 +#: .\ldt_utils\views\content.py:192 msgid "Problem when uploading file : " msgstr "Problème lors de l'upload du fichier : " -#: .\ldt_utils\views\content.py:301 +#: .\ldt_utils\views\content.py:297 +msgid "Content creation failure" +msgstr "Echec lors de la creation du contenu" + +#: .\ldt_utils\views\content.py:305 +msgid "Commit of the content creation failed" +msgstr "Echec lors du commit de la creation du contenu" + +#: .\ldt_utils\views\content.py:325 #, 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\content.py:302 +#: .\ldt_utils\views\content.py:326 msgid "title error deleting content" msgstr "Erreur lors de l'effacement du contenu" -#: .\ldt_utils\views\content.py:304 +#: .\ldt_utils\views\content.py:331 #, python-format msgid "Confirm delete content %(titles)s" msgstr "Veuillez confirmer l'effacement du contenu %(titles)s" -#: .\ldt_utils\views\content.py:305 +#: .\ldt_utils\views\content.py:332 msgid "confirm delete content" msgstr "Confirmation effacement contenu" -#: .\ldt_utils\views\content.py:317 +#: .\ldt_utils\views\content.py:343 #, python-format msgid "Please unpublish the front project %(title)s" msgstr "Veuillez dépublier le projet : %(title)s" -#: .\ldt_utils\views\content.py:318 +#: .\ldt_utils\views\content.py:344 msgid "The front project is published" msgstr "Projet publié" -#: .\ldt_utils\views\content.py:319 .\ldt_utils\views\content.py:322 +#: .\ldt_utils\views\content.py:345 .\ldt_utils\views\content.py:348 #: .\ldt_utils\views\project.py:137 msgid "confirm reset" msgstr "Confirmer la réinitialisation" -#: .\ldt_utils\views\content.py:321 .\ldt_utils\views\project.py:136 +#: .\ldt_utils\views\content.py:347 .\ldt_utils\views\project.py:136 #, python-format msgid "please confirm reseting project %(title)s" msgstr "Veuillez confirmer la réinitialisation du projet %(title)s" -#: .\ldt_utils\views\content.py:382 +#: .\ldt_utils\views\content.py:375 +msgid "An error occurred - Please try again or contact webmaster" +msgstr "Une erreur est apparue - Merci de réessayer ou de contacter le webmaster" + +#: .\ldt_utils\views\content.py:376 +#, fuzzy +msgid "Error" +msgstr "Erreur" + +#: .\ldt_utils\views\content.py:419 #, python-format msgid "" "Content '%(title)s' is referenced by this project : %(project_titles)s. " @@ -993,6 +1010,24 @@ "Le contenu '%(title)s' est référencé par les projets suivants : '%" "(project_titles)s'.Veuillez les effacer préalablement." +#: .\ldt_utils\views\content.py:424 +#, python-format +msgid "" +"The project '%(project_title)s' pointing on the content '%(title)s' has " +"several annotations. Do you want to delete the content and the project " +"anyway ?" +msgstr "" +"Le projet '%(project_title)s' référençant le contenu '%(title)s' comporte " +"plusieurs annotations. Voulez vous quand même supprimer le contenu ?" + +#: .\ldt_utils\views\content.py:452 +msgid "Content deletion failure" +msgstr "Echec lors de la suppression du contenu" + +#: .\ldt_utils\views\content.py:462 +msgid "Commit of the content deletion failed" +msgstr "Echec lors du commit de la suppression du contenu" + #: .\ldt_utils\views\json.py:40 .\ldt_utils\views\rdf.py:15 #: .\ldt_utils\views\workspace.py:175 msgid "You can not access this project" @@ -1033,11 +1068,11 @@ #: .\ldt_utils\views\workspace.py:125 msgid "" "The content does not exists or you are not allowed to access this content" -msgstr "" +msgstr "Ce contenu n'existe pas, ou vous n'êtes pas autorisé a y acceder" #: .\ldt_utils\views\workspace.py:129 msgid "Parameters project_id or content_id must be given in the url" -msgstr "" +msgstr "Les paramètres project_id et content_id doivent être passés dans l'URL" #: .\templates\admin\cms_change_form.html.py:30 msgid "Approve page deletion" diff -r e5b5e9d56eec -r 7f237270b61c src/ldt/ldt/security/utils.py --- a/src/ldt/ldt/security/utils.py Wed Oct 10 17:55:18 2012 +0200 +++ b/src/ldt/ldt/security/utils.py Wed Oct 10 18:07:40 2012 +0200 @@ -41,9 +41,10 @@ new_content = c_cls.safe_objects.filter(iri_id=content.iri_id) if new_content: - media = m_cls.safe_objects.filter(id=new_content[0].media_obj.id) - if not media: - return True + if new_content[0].media_obj: + media = m_cls.safe_objects.filter(id=new_content[0].media_obj.id) + if not media: + return True return False def add_change_attr(user, obj_list):