def new_image(request, gal_pk): ''' Creates a new image ''' gal = get_object_or_404(Gallery, pk=gal_pk) if request.method == 'POST': form = ImageForm(request.POST, request.FILES) if form.is_valid() \ and request.FILES['physical'].size < settings.IMAGE_MAX_SIZE: img = Image() img.physical = request.FILES['physical'] img.gallery = gal img.title = request.POST['title'] img.slug = slugify(request.FILES['physical']) img.legend = request.POST['legend'] img.pubdate = datetime.now() img.save() # Redirect to the document list after POST return redirect(gal.get_absolute_url()) else: # TODO: add errors to the form and return it raise Http404 else: form = ImageForm() # A empty, unbound form return render_template('gallery/new_image.html', { 'form': form, 'gallery': gal })
def perform_create(self, title, physical, legend=""): """Create a new image :param title: title :type title: str :param physical: :type physical: file :param legend: legend (optional) :type legend: str """ if physical.size > settings.ZDS_APP["gallery"]["image_max_size"]: raise ImageTooLarge(title, physical.size) try: ImagePIL.open(physical) except OSError: raise NotAnImage(physical) image = Image() image.gallery = self.gallery image.title = title if legend: image.legend = legend else: image.legend = image.title image.physical = physical image.slug = slugify(title) image.pubdate = datetime.datetime.now() image.save() self.image = image return self.image
def new_image(request, gal_pk): """Creates a new image.""" gal = get_object_or_404(Gallery, pk=gal_pk) # check if the user can upload new image in this gallery try: gal_mode = UserGallery.objects.get(gallery=gal, user=request.user) if gal_mode.mode != 'W': raise PermissionDenied except: raise PermissionDenied if request.method == "POST": form = ImageForm(request.POST, request.FILES) if form.is_valid() and request.FILES["physical"].size < settings.IMAGE_MAX_SIZE: img = Image() img.physical = request.FILES["physical"] img.gallery = gal img.title = request.POST["title"] img.slug = slugify(request.FILES["physical"]) img.legend = request.POST["legend"] img.pubdate = datetime.now() img.save() # Redirect to the newly uploaded image edit page after POST return redirect(reverse("zds.gallery.views.edit_image", args=[gal.pk, img.pk])) else: return render_template("gallery/image/new.html", {"form": form, "gallery": gal}) else: form = ImageForm(initial={"new_image": True}) # A empty, unbound form return render_template("gallery/image/new.html", {"form": form, "gallery": gal})
def form_valid(self, form): # create the object: self.content = PublishableContent() self.content.title = form.cleaned_data["title"] self.content.description = form.cleaned_data["description"] self.content.type = form.cleaned_data["type"] self.content.licence = self.request.user.profile.licence # Use the preferred license of the user if it exists self.content.source = form.cleaned_data["source"] self.content.creation_date = datetime.now() # Creating the gallery gal = Gallery() gal.title = form.cleaned_data["title"] gal.slug = slugify(form.cleaned_data["title"]) gal.pubdate = datetime.now() gal.save() self.content.gallery = gal self.content.save() # create image: if "image" in self.request.FILES: img = Image() img.physical = self.request.FILES["image"] img.gallery = gal img.title = self.request.FILES["image"] img.slug = slugify(self.request.FILES["image"].name) img.pubdate = datetime.now() img.save() self.content.image = img self.content.save() # We need to save the content before changing its author list since it's a many-to-many relationship self.content.authors.add(self.request.user) self.content.ensure_author_gallery() self.content.save() # Add subcategories on tutorial for subcat in form.cleaned_data["subcategory"]: self.content.subcategory.add(subcat) self.content.save() # create a new repo : init_new_repo( self.content, form.cleaned_data["introduction"], form.cleaned_data["conclusion"], form.cleaned_data["msg_commit"], ) return super(CreateContent, self).form_valid(form)
def new_image(request, gal_pk): """Creates a new image.""" gal = get_object_or_404(Gallery, pk=gal_pk) # check if the user can upload new image in this gallery try: gal_mode = UserGallery.objects.get(gallery=gal, user=request.user) if gal_mode.mode != 'W': raise PermissionDenied except: raise PermissionDenied if request.method == "POST": form = ImageForm(request.POST, request.FILES) if form.is_valid(): img = Image() img.physical = request.FILES["physical"] img.gallery = gal img.title = request.POST["title"] img.slug = slugify(request.FILES["physical"]) img.legend = request.POST["legend"] img.pubdate = datetime.now() img.save() # Redirect to the newly uploaded image edit page after POST return redirect( reverse("zds.gallery.views.edit_image", args=[gal.pk, img.pk])) else: return render_template("gallery/image/new.html", { "form": form, "gallery": gal }) else: form = ImageForm(initial={"new_image": True}) # A empty, unbound form return render_template("gallery/image/new.html", { "form": form, "gallery": gal })
def use_images_from_archive(request, zip_file, versioned_content, gallery): """Extract image from a gallery and then translate the ``![.+](prefix:filename)`` into the final image we want. The ``prefix`` is defined into the settings. Note that this function does not perform any commit. :param zip_file: ZIP archive :type zip_file: zipfile.ZipFile :param versioned_content: content :type versioned_content: VersionedContent :param gallery: gallery of image :type gallery: Gallery """ translation_dic = {} # create a temporary directory: temp = os.path.join(tempfile.gettempdir(), str(time.time())) if not os.path.exists(temp): os.makedirs(temp) for image_path in zip_file.namelist(): image_basename = os.path.basename(image_path) if not image_basename.strip(): # don't deal with directory continue temp_image_path = os.path.abspath( os.path.join(temp, image_basename)) # create a temporary file for the image f_im = open(temp_image_path, "wb") f_im.write(zip_file.read(image_path)) f_im.close() # if it's not an image, pass try: ImagePIL.open(temp_image_path) except OSError: continue # if size is too large, pass if os.stat(temp_image_path).st_size > settings.ZDS_APP["gallery"][ "image_max_size"]: messages.error( request, _('Votre image "{}" est beaucoup trop lourde, réduisez sa taille à moins de {:.0f}' "Kio avant de l'envoyer.").format( image_path, settings.ZDS_APP["gallery"]["image_max_size"] / 1024), ) continue # create picture in database: pic = Image() pic.gallery = gallery pic.title = image_basename pic.slug = slugify(image_basename) pic.physical = get_thumbnailer(open(temp_image_path, "rb"), relative_name=temp_image_path) pic.pubdate = datetime.now() pic.save() translation_dic[image_path] = settings.ZDS_APP["site"][ "url"] + pic.physical.url # finally, remove image if os.path.exists(temp_image_path): os.remove(temp_image_path) zip_file.close() if os.path.exists(temp): shutil.rmtree(temp) # then, modify each extracts image_regex = re.compile( r"((?P<start>!\[.*?\]\()" + settings.ZDS_APP["content"]["import_image_prefix"] + r":(?P<path>.*?)(?P<end>\)))") for element in versioned_content.traverse(only_container=False): if isinstance(element, Container): introduction = element.get_introduction() introduction = image_regex.sub( lambda g: UpdateContentWithArchive.update_image_link( g, translation_dic), introduction) conclusion = element.get_conclusion() conclusion = image_regex.sub( lambda g: UpdateContentWithArchive.update_image_link( g, translation_dic), conclusion) element.repo_update(element.title, introduction, conclusion, do_commit=False) else: section_text = element.get_text() section_text = image_regex.sub( lambda g: UpdateContentWithArchive.update_image_link( g, translation_dic), section_text) element.repo_update(element.title, section_text, do_commit=False)
def migrate_articles(): articles = Article.objects.all() if len(articles) == 0: return for i in progressbar(xrange(len(articles)), "Exporting articles", 100): current = articles[i] if not os.path.exists(current.get_path(False)): sys.stderr.write( 'Invalid physical path to repository « {} », skipping\n'. format(current.get_path(False))) continue exported = PublishableContent() exported.slug = current.slug exported.type = "ARTICLE" exported.title = current.title exported.creation_date = current.create_at exported.description = current.description exported.sha_draft = current.sha_draft exported.sha_validation = current.sha_validation exported.licence = current.licence exported.js_support = current.js_support exported.pubdate = current.pubdate exported.save( ) # before updating `ManyToMany` relation, we need to save ! try: clean_commit = copy_and_clean_repo(current.get_path(False), exported.get_repo_path(False)) except InvalidGitRepositoryError as e: exported.delete() sys.stderr.write( 'Repository in « {} » is invalid, skipping\n'.format(e)) continue if clean_commit: exported.sha_draft = clean_commit # save clean up in old module to avoid any trouble current.sha_draft = clean_commit current.save() [exported.authors.add(author) for author in current.authors.all()] [ exported.subcategory.add(category) for category in current.subcategory.all() ] new_gallery = create_gallery_for_article(exported) if current.image: # migrate image using `Image()` try: path_to_image = current.image['article_illu'].url except InvalidImageFormatError: pass else: img = Image() # Create a new name for our image filename = os.path.basename(current.image['article_illu'].url) # Find original name split = filename.split('.') original_filename = split[0] + '.' + split[1] if "None" in path_to_image: # Move image in the gallery folder shutil.copyfile( os.path.join(MEDIA_ROOT, 'articles', 'None', original_filename), os.path.join(new_gallery.get_gallery_path(), original_filename)) # Update image information img.physical = os.path.join('galleries', str(new_gallery.pk), original_filename) else: # Move image in the gallery folder shutil.copyfile( os.path.join(MEDIA_ROOT, 'articles', str(current.id), original_filename), os.path.join(new_gallery.get_gallery_path(), original_filename)) # Update image information img.physical = os.path.join('galleries', str(new_gallery.pk), original_filename) img.title = 'icone de l\'article' img.slug = slugify(filename) img.pubdate = datetime.now() img.gallery = new_gallery img.save() exported.image = img # now, re create the manifest.json versioned = exported.load_version() versioned.type = "ARTICLE" if exported.licence: versioned.licence = exported.licence split_article_in_extracts(versioned) # create extracts from text exported.sha_draft = versioned.commit_changes(u'Migration version 2') exported.old_pk = current.pk exported.save() reacts = Reaction.objects.filter(article__pk=current.pk)\ .select_related("author")\ .order_by("pubdate")\ .all() if current.last_reaction: export_comments(reacts, exported, ArticleRead, current.last_reaction.pk) migrate_validation( exported, ArticleValidation.objects.filter(article__pk=current.pk)) if current.sha_public is not None and current.sha_public != "": # set mapping map_previous = PublishedContent() map_previous.content_public_slug = current.slug map_previous.content_pk = current.pk map_previous.content_type = 'ARTICLE' map_previous.must_redirect = True # will send HTTP 301 if visited ! map_previous.content = exported map_previous.save() # publish the article ! published = publish_content( exported, exported.load_version(exported.sha_draft), False) exported.pubdate = current.pubdate exported.update_date = current.update exported.sha_public = exported.sha_draft exported.public_version = published exported.save() published.content_public_slug = exported.slug published.publication_date = exported.pubdate published.save() # as we changed the structure we have to update the validation history. Yes, it's ugly. last_validation = Validation.objects.filter( content__pk=exported.pk).last() structure_validation = Validation( content=exported, version=exported.sha_public, comment_authors="Migration v2", comment_validator="yeah", status="ACCEPT", validator=last_validation.validator, date_proposition=datetime.now(), date_validation=datetime.now(), date_reserve=datetime.now()) structure_validation.save() # fix strange notification bug authors = list(exported.authors.all()) reads_to_delete = ContentRead.objects\ .filter(content=exported)\ .exclude(user__pk__in=ContentReaction.objects .filter(related_content=exported) .exclude(author__in=authors) .values_list("author__pk", flat=True)) for read in reads_to_delete.all(): read.delete()
def form_valid(self, form): versioned = self.versioned_object publishable = self.object # check if content has changed: current_hash = versioned.compute_hash() if current_hash != form.cleaned_data["last_hash"]: data = form.data.copy() data["last_hash"] = current_hash data["introduction"] = versioned.get_introduction() data["conclusion"] = versioned.get_conclusion() form.data = data messages.error( self.request, _("Une nouvelle version a été postée avant que vous ne validiez." )) return self.form_invalid(form) # Forbid removing all categories of a validated content if publishable.in_public() and not form.cleaned_data["subcategory"]: messages.error( self.request, _("Vous devez choisir au moins une catégorie, car ce contenu est déjà publié." )) return self.form_invalid(form) # first, update DB (in order to get a new slug if needed) title_is_changed = publishable.title != form.cleaned_data["title"] publishable.title = form.cleaned_data["title"] publishable.description = form.cleaned_data["description"] publishable.source = form.cleaned_data["source"] publishable.update_date = datetime.now() # update gallery and image: gal = Gallery.objects.filter(pk=publishable.gallery.pk) gal.update(title=publishable.title) gal.update(slug=slugify(publishable.title)) gal.update(update=datetime.now()) if "image" in self.request.FILES: img = Image() img.physical = self.request.FILES["image"] img.gallery = publishable.gallery img.title = self.request.FILES["image"] img.slug = slugify(self.request.FILES["image"].name) img.pubdate = datetime.now() img.save() publishable.image = img publishable.save(force_slug_update=title_is_changed) logger.debug("content %s updated, slug is %s", publishable.pk, publishable.slug) # now, update the versioned information versioned.description = form.cleaned_data["description"] sha = versioned.repo_update_top_container( form.cleaned_data["title"], publishable.slug, form.cleaned_data["introduction"], form.cleaned_data["conclusion"], form.cleaned_data["msg_commit"], ) logger.debug("slug consistency after repo update repo=%s db=%s", versioned.slug, publishable.slug) # update relationships : publishable.sha_draft = sha publishable.subcategory.clear() for subcat in form.cleaned_data["subcategory"]: publishable.subcategory.add(subcat) publishable.save() self.success_url = reverse("content:view", args=[publishable.pk, publishable.slug]) return super().form_valid(form)