Пример #1
0
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
        })
Пример #2
0
    def set_avatar_from_file(self, avatar, filename='avatar.png'):
        """
        Updates the avatar of this user from a file, creating a gallery on his account
        if needed and adding the avatar to the gallery.
        :param avatar: The avatar file (file-like object).
        :param filename: The file name, including the type extension.
        """
        user_gallery = UserGallery.objects.filter(gallery__title=ZDS_APP['gallery']['avatars_gallery'], user=self.user)\
            .first()

        if not user_gallery:
            gallery = Gallery()
            gallery.title = ZDS_APP['gallery']['avatars_gallery']
            gallery.subtitle = ''
            gallery.slug = slugify(ZDS_APP['gallery']['avatars_gallery'])
            gallery.pubdate = datetime.now()
            gallery.save()

            user_gallery = UserGallery()
            user_gallery.gallery = gallery
            user_gallery.mode = GALLERY_WRITE
            user_gallery.user = self.user
            user_gallery.save()

        image = Image()
        image.title = _('Avatar')
        image.legend = _('Avatar importé')
        image.gallery = user_gallery.gallery
        image.physical = get_thumbnailer(avatar, relative_name=filename)
        image.pubdate = datetime.now()
        image.save()

        self.avatar_url = image.get_absolute_url()
Пример #3
0
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})
Пример #4
0
    def form_valid(self, form):
        context = self.get_context_data()
        gallery = context['gallery']

        archive = self.request.FILES["file"]
        temp = os.path.join(tempfile.gettempdir(), str(time.time()))

        if not os.path.exists(temp):
            os.makedirs(temp)
        zfile = zipfile.ZipFile(archive, "a")

        for i in zfile.namelist():
            filename = os.path.split(i)[1]

            ph_temp = os.path.abspath(os.path.join(temp, os.path.basename(i)))

            if filename.strip() == "":  # don't deal with directory
                continue

            # create file for image
            f_im = open(ph_temp, "wb")
            f_im.write(zfile.read(i))
            f_im.close()
            title = os.path.basename(i)

            # if size is too large, don't save
            if os.stat(ph_temp).st_size > settings.ZDS_APP['gallery']['image_max_size']:
                messages.error(
                    self.request, _(u'Votre image "{}" est beaucoup trop lourde, réduisez sa taille à moins de {:.0f}'
                                    u'Kio avant de l\'envoyer.').format(
                                        title, settings.ZDS_APP['gallery']['image_max_size'] / 1024))
                continue

            # if it's not an image, pass
            try:
                ImagePIL.open(ph_temp)
            except IOError:
                continue

            # create picture in database:
            f_im = File(open(ph_temp, "rb"))
            f_im.name = title

            pic = Image()
            pic.gallery = gallery
            pic.title = title
            pic.pubdate = datetime.now()
            pic.physical = f_im
            pic.save()
            f_im.close()

            if os.path.exists(ph_temp):
                os.remove(ph_temp)

        zfile.close()

        if os.path.exists(temp):
            shutil.rmtree(temp)

        return redirect(gallery.get_absolute_url())
Пример #5
0
    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)
Пример #6
0
    def form_valid(self, form):

        context = self.get_context_data(**self.kwargs)

        img = Image()
        img.gallery = context['gallery']
        img.title = form.cleaned_data['title']

        if form.cleaned_data['legend'] and form.cleaned_data['legend'] != '':
            img.legend = form.cleaned_data['legend']
        else:
            img.legend = img.title

        img.physical = self.request.FILES['physical']
        img.pubdate = datetime.now()
        img.save()

        return redirect(reverse('gallery-image-edit', args=[img.gallery.pk, img.pk]))
Пример #7
0
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
        })
Пример #8
0
    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)
Пример #9
0
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()
Пример #10
0
    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)
Пример #11
0
    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