Exemple #1
0
    def __call__(self, form, field):
        field_data_length = field.data and len(field.data) or 0

        if (field_data_length < self.min
                or self.max != -1 and field_data_length > self.max):
            message = self.message
            if message is None:
                if self.max == -1:
                    message = _n(
                        "Field must be at least %(min)d character long.",
                        "Field must be at least %(min)d characters long.",
                        self.min,
                        min=self.min,
                    )
                elif self.min == -1:
                    message = _n(
                        "Field cannot be longer than %(max)d character.",
                        "Field cannot be longer than %(max)d characters.",
                        self.max,
                        max=self.max,
                    )
                else:
                    message = _(
                        "Field must be between %(min)d and %(max)d characters long.",
                        min=self.min,
                        max=self.max,
                    )
            raise validators.ValidationError(message % {
                "min": self.min,
                "max": self.max,
                "length": field_data_length
            })
Exemple #2
0
    def __call__(self, form, field):
        field_data_length = field.data and len(field.data) or 0

        if (
            field_data_length < self.min
            or self.max != -1
            and field_data_length > self.max
        ):
            message = self.message
            if message is None:
                if self.max == -1:
                    message = _n(
                        "Field must be at least %(min)d character long.",
                        "Field must be at least %(min)d characters long.",
                        self.min,
                        min=self.min,
                    )
                elif self.min == -1:
                    message = _n(
                        "Field cannot be longer than %(max)d character.",
                        "Field cannot be longer than %(max)d characters.",
                        self.max,
                        max=self.max,
                    )
                else:
                    message = _(
                        "Field must be between %(min)d and %(max)d characters long.",
                        min=self.min,
                        max=self.max,
                    )
            raise validators.ValidationError(
                message
                % {"min": self.min, "max": self.max, "length": field_data_length}
            )
Exemple #3
0
    def __call__(self, form, field):
        l = field.data and len(field.data) or 0

        if l < self.min or self.max != -1 and l > self.max:
            message = self.message
            if message is None:
                if self.max == -1:
                    message = _n(
                        u'Field must be at least %(min)d character long.',
                        u'Field must be at least %(min)d characters long.',
                        self.min,
                        min=self.min)
                elif self.min == -1:
                    message = _n(
                        u'Field cannot be longer than %(max)d character.',
                        u'Field cannot be longer than %(max)d characters.',
                        self.max,
                        max=self.max)
                else:
                    message = _(
                        u'Field must be between %(min)d and %(max)d characters long.',
                        min=self.min,
                        max=self.max)
            raise ValidationError(message %
                                  dict(min=self.min, max=self.max, length=l))
Exemple #4
0
    def do_delete(self):
        data = request.form
        confirm = data.get("confirm_delete", False, type=bool)

        if not confirm:
            flash(_("Please fix the error(s) below"), "error")
            self.form_errors["confirm_delete"] = _(
                "Must be checked to ensure you " "intent to delete these tags"
            )
            return self.get(self.ns)

        session = db.session()
        tags = self._get_selected_tags()

        if not tags:
            flash(_("No action performed: no tags selected"), "warning")
            return self.redirect_to_view()

        count = len(tags)
        entities_to_reindex = get_entities_for_reindex(tags)
        success_message = _n(
            "%(tag)s deleted",
            "%(num)d tags deleted:\n%(tags)s",
            count,
            tag=tags[0].label,
            tags=", ".join(t.label for t in tags),
        )
        for tag in tags:
            session.delete(tag)
        session.commit()
        flash(success_message)
        schedule_entities_reindex(entities_to_reindex)
        return self.redirect_to_view()
Exemple #5
0
    def do_delete(self):
        data = request.form
        confirm = data.get('confirm_delete', False, type=bool)

        if not confirm:
            flash(_(u'Please fix the error(s) below'), 'error')
            self.form_errors['confirm_delete'] = _(
                u'Must be checked to ensure you '
                u'intent to delete these tags')
            return self.get(self.ns)

        session = current_app.db.session()
        tags = self._get_selected_tags()

        if not tags:
            flash(_(u'No action performed: no tags selected'), 'warning')
            return self.redirect_to_view()

        count = len(tags)
        entities_to_reindex = get_entities_for_reindex(tags)
        success_message = _n(u'%(tag)s deleted',
                             u'%(num)d tags deleted:\n%(tags)s',
                             count,
                             tag=tags[0].label,
                             tags=u', '.join(t.label for t in tags))
        map(session.delete, tags)
        session.commit()
        flash(success_message)
        schedule_entities_reindex(entities_to_reindex)
        return self.redirect_to_view()
Exemple #6
0
  def do_delete(self):
    data = request.form
    confirm = data.get('confirm_delete', False, type=bool)

    if not confirm:
      flash(_(u'Please fix the error(s) below'), 'error')
      self.form_errors['confirm_delete'] = _(u'Must be checked to ensure you '
                                             u'intent to delete these tags')
      return self.get(self.ns)

    session = current_app.db.session()
    tags = self._get_selected_tags()

    if not tags:
      flash(_(u'No action performed: no tags selected'), 'warning')
      return self.redirect_to_view()

    count = len(tags)
    entities_to_reindex = get_entities_for_reindex(tags)
    success_message = _n(u'%(tag)s deleted',
                         u'%(num)d tags deleted:\n%(tags)s',
                         count,
                         tag=tags[0].label,
                         tags=u', '.join(t.label for t in tags))
    map(session.delete, tags)
    session.commit()
    flash(success_message)
    schedule_entities_reindex(entities_to_reindex)
    return self.redirect_to_view()
Exemple #7
0
    def do_delete(self):
        data = request.form
        confirm = data.get("confirm_delete", False, type=bool)

        if not confirm:
            flash(_("Please fix the error(s) below"), "error")
            self.form_errors["confirm_delete"] = _(
                "Must be checked to ensure you "
                "intent to delete these tags")
            return self.get(self.ns)

        session = db.session()
        tags = self._get_selected_tags()

        if not tags:
            flash(_("No action performed: no tags selected"), "warning")
            return self.redirect_to_view()

        count = len(tags)
        entities_to_reindex = get_entities_for_reindex(tags)
        success_message = _n(
            "%(tag)s deleted",
            "%(num)d tags deleted:\n%(tags)s",
            count,
            tag=tags[0].label,
            tags=", ".join(t.label for t in tags),
        )
        for tag in tags:
            session.delete(tag)
        session.commit()
        flash(success_message)
        schedule_entities_reindex(entities_to_reindex)
        return self.redirect_to_view()
Exemple #8
0
  def __call__(self, form, field):
    l = field.data and len(field.data) or 0

    if l < self.min or self.max != -1 and l > self.max:
      message = self.message
      if message is None:
        if self.max == -1:
          message = _n(u'Field must be at least %(min)d character long.',
                       u'Field must be at least %(min)d characters long.',
                       self.min, min=self.min)
        elif self.min == -1:
          message = _n(u'Field cannot be longer than %(max)d character.',
                       u'Field cannot be longer than %(max)d characters.',
                       self.max, max=self.max)
        else:
          message = _(
            u'Field must be between %(min)d and %(max)d characters long.',
            min=self.min, max=self.max)
      raise ValidationError(message % dict(min=self.min, max=self.max, length=l))
Exemple #9
0
def delete_multiple(folder):
    check_write_access(folder)

    folders, docs = get_selected_objects(folder)

    for obj in docs + folders:
        app = unwrap(current_app)
        community = g.community._model
        activity.send(app,
                      actor=current_user,
                      verb="delete",
                      object=obj,
                      target=community)
        repository.delete_object(obj)

    if docs + folders:
        db.session.commit()
        if docs and folders:
            msg = _(
                "%(file_num)d files and %(folder_num)d folders sucessfully "
                "deleted.",
                file_num=len(docs),
                folder_num=len(folders),
            )
        elif docs and not folders:
            msg = _n(
                "1 file sucessfully deleted.",
                "%(num)d files sucessfully deleted.",
                num=len(docs),
            )
        else:
            msg = _n(
                "1 folder sucessfully deleted.",
                "%(num)d folders sucessfully deleted.",
                num=len(folders),
            )

        flash(msg, "success")
    else:
        flash(_("No object deleted"), "error")

    return redirect(url_for(folder))
Exemple #10
0
def delete_multiple(folder):
    check_write_access(folder)

    folders, docs = get_selected_objects(folder)

    for obj in docs + folders:
        app = unwrap(current_app)
        community = g.community._model
        activity.send(
            app, actor=current_user, verb="delete", object=obj, target=community
        )
        repository.delete_object(obj)

    if docs + folders:
        db.session.commit()
        if docs and folders:
            msg = _(
                "%(file_num)d files and %(folder_num)d folders sucessfully " "deleted.",
                file_num=len(docs),
                folder_num=len(folders),
            )
        elif docs and not folders:
            msg = _n(
                "1 file sucessfully deleted.",
                "%(num)d files sucessfully deleted.",
                num=len(docs),
            )
        else:
            msg = _n(
                "1 folder sucessfully deleted.",
                "%(num)d folders sucessfully deleted.",
                num=len(folders),
            )

        flash(msg, "success")
    else:
        flash(_("No object deleted"), "error")

    return redirect(url_for(folder))
Exemple #11
0
def upload_new(folder):
    check_write_access(folder)
    session = db.session()
    base_folder = folder
    uncompress_files = "uncompress_files" in request.form
    fds = request.files.getlist("file")
    created_count = 0
    path_cache = {}  # mapping folder path in zip: folder instance

    for upload_fd in fds:
        for filepath, fd in explore_archive(upload_fd,
                                            uncompress=uncompress_files):
            folder = base_folder
            parts = []
            # traverse to final directory, create intermediate if necessary. Folders
            # may be renamed if a file already exists, path_cache is used to keep
            # track of this
            for subfolder_name in filepath:
                parts.append(subfolder_name)
                path = "/".join(parts)
                if path in path_cache:
                    folder = path_cache[path]
                    continue

                subfolders = {f.title: f for f in folder.subfolders}
                if subfolder_name in subfolders:
                    folder = subfolders[subfolder_name]
                    path_cache[path] = folder
                    continue

                subfolder_name = get_new_filename(folder, subfolder_name)
                folder = folder.create_subfolder(subfolder_name)
                session.flush()
                path_cache[path] = folder

            create_document(folder, fd)
            created_count += 1

    flash(
        _n(
            "One new document successfully uploaded",
            "%(num)d new document successfully uploaded",
            num=created_count,
        ),
        "success",
    )

    session.commit()
    return redirect(url_for(folder))
Exemple #12
0
def upload_new(folder):
    check_write_access(folder)
    session = db.session()
    base_folder = folder
    uncompress_files = "uncompress_files" in request.form
    fds = request.files.getlist("file")
    created_count = 0
    path_cache = {}  # mapping folder path in zip: folder instance

    for upload_fd in fds:
        for filepath, fd in explore_archive(upload_fd, uncompress=uncompress_files):
            folder = base_folder
            parts = []
            # traverse to final directory, create intermediate if necessary. Folders
            # may be renamed if a file already exists, path_cache is used to keep
            # track of this
            for subfolder_name in filepath:
                parts.append(subfolder_name)
                path = "/".join(parts)
                if path in path_cache:
                    folder = path_cache[path]
                    continue

                subfolders = {f.title: f for f in folder.subfolders}
                if subfolder_name in subfolders:
                    folder = subfolders[subfolder_name]
                    path_cache[path] = folder
                    continue

                subfolder_name = get_new_filename(folder, subfolder_name)
                folder = folder.create_subfolder(subfolder_name)
                session.flush()
                path_cache[path] = folder

            create_document(folder, fd)
            created_count += 1

    flash(
        _n(
            "One new document successfully uploaded",
            "%(num)d new document successfully uploaded",
            num=created_count,
        ),
        "success",
    )

    session.commit()
    return redirect(url_for(folder))
Exemple #13
0
def attachment_upload():
    title = request.args["title"].strip()
    try:
        page = get_page_by_title(title)
    except NoResultFound:
        raise NotFound()

    files = request.files.getlist("attachments")
    saved_count = 0

    for f in files:
        name = f.filename
        if not isinstance(name, str):
            name = str(f.filename, encoding="utf-8", errors="ignore")

        # FIXME: do something instead of just skipping the attachement
        if not name:
            continue

        attachment = WikiPageAttachment(name=name)
        attachment.wikipage = page
        attachment.set_content(f.read(), f.content_type)
        db.session.add(attachment)
        saved_count += 1

    if saved_count:
        db.session.commit()
        flash(
            _n(
                "One new document successfully uploaded",
                "%(num)d new documents successfully uploaded",
                count=saved_count,
                num=len(files),
            ),
            "success",
        )
    else:
        flash(_("No file uploaded."))

    return redirect(url_for(page))
Exemple #14
0
def attachment_upload():
    title = request.args["title"].strip()
    try:
        page = get_page_by_title(title)
    except NoResultFound:
        raise NotFound()

    files = request.files.getlist("attachments")
    saved_count = 0

    for f in files:
        name = f.filename
        if not isinstance(name, text_type):
            name = text_type(f.filename, encoding="utf-8", errors="ignore")

        # FIXME: do something instead of just skipping the attachement
        if not name:
            continue

        attachment = WikiPageAttachment(name=name)
        attachment.wikipage = page
        attachment.set_content(f.read(), f.content_type)
        db.session.add(attachment)
        saved_count += 1

    if saved_count:
        db.session.commit()
        flash(
            _n(
                "One new document successfully uploaded",
                "%(num)d new documents successfully uploaded",
                count=saved_count,
                num=len(files),
            ),
            "success",
        )
    else:
        flash(_("No file uploaded."))

    return redirect(url_for(page))
Exemple #15
0
def move_multiple(folder):
    folders, docs = get_selected_objects(folder)
    count_f = len(folders)
    count_d = len(docs)
    current_folder_url = url_for(folder)

    if not (count_f + count_d):
        flash(_('Move elements: no elements selected.'), 'info')
        return redirect(current_folder_url)

    try:
        target_folder_id = int(request.form.get('target-folder'))
    except ValueError:
        flash(_('Move elements: no destination folder selected. Aborted.'),
              'error')
        return redirect(current_folder_url)

    target_folder = repository.get_folder_by_id(target_folder_id)

    if folder == target_folder:
        flash(
            _('Move elements: source and destination folder are identical,'
              ' nothing done.'), 'error')
        return redirect(current_folder_url)

    if not security.has_permission(g.user, 'write', folder, inherit=True):
        # this should not happen: this is just defensive programming
        flash(_('You are not allowed to move elements from this folder'),
              'error')
        return redirect(current_folder_url)

    if not security.has_permission(
            g.user, 'write', target_folder, inherit=True):
        flash(
            _('You are not allowed to write in folder "{folder}"').format(
                folder=target_folder.title), 'error')
        return redirect(current_folder_url)

    for item in itertools.chain(folders, docs):
        # FIXME: maybe too brutal
        check_write_access(item)

    # verify we are not trying to move a folder inside itself or one of its
    # descendants
    f = target_folder
    while f:
        if f in folders:
            flash(
                _('Move elements: destination folder is included in moved '
                  'elements. Moved nothing.'), 'error')
            return redirect(url_for(folder))
        f = f.parent

    exist_in_dest = []
    for item in itertools.chain(folders, docs):
        try:
            with db.session.begin_nested():
                item.parent = target_folder
        except sa.exc.IntegrityError:
            exist_in_dest.append(item)

    if exist_in_dest:
        # items existing in destination: cancel operation
        db.session.rollback()
        msg = _('Move elements: canceled, some elements exists in destination '
                'folder: {elements}')
        elements = ', '.join('"{}"'.format(i.title) for i in exist_in_dest)
        flash(msg.format(elements=elements), 'error')
        return redirect(current_folder_url)

    db.session.commit()

    msg_f = (_n('1 folder', '{count} folders', count_f)
             if count_f else _('0 folder')).format(count=count_f)

    msg_d = (_n('1 document', '{count} documents', count_d)
             if count_d else _('0 document')).format(count=count_d)

    msg = _('{folders} and {documents} moved to {target}').format(
        folders=msg_f, documents=msg_d, target=target_folder.title)
    flash(msg, 'success')

    return redirect(url_for(folder))
Exemple #16
0
 def ngettext(self, singular, plural, n):
     return _n(singular, plural, n)
Exemple #17
0
def move_multiple(folder: Folder) -> Response:
    folders, docs = get_selected_objects(folder)
    objects = folders + docs

    count_f = len(folders)
    count_d = len(docs)
    current_folder_url = url_for(folder)

    if not (count_f + count_d):
        flash(_("Move elements: no elements selected."), "info")
        return redirect(current_folder_url)

    try:
        target_folder_id = int(request.form["target-folder"])
    except ValueError:
        flash(_("Move elements: no destination folder selected. Aborted."), "error")
        return redirect(current_folder_url)

    target_folder = repository.get_folder_by_id(target_folder_id)

    if folder == target_folder:
        flash(
            _(
                "Move elements: source and destination folder are identical,"
                " nothing done."
            ),
            "error",
        )
        return redirect(current_folder_url)

    if not security.has_permission(current_user, "write", folder, inherit=True):
        # this should not happen: this is just defensive programming
        flash(_("You are not allowed to move elements from this folder"), "error")
        return redirect(current_folder_url)

    if not security.has_permission(current_user, "write", target_folder, inherit=True):
        flash(
            _('You are not allowed to write in folder "{folder}"').format(
                folder=target_folder.title
            ),
            "error",
        )
        return redirect(current_folder_url)

    for item in objects:
        # FIXME: maybe too brutal
        check_write_access(item)

    # verify we are not trying to move a folder inside itself or one of its
    # descendants
    f = target_folder
    while f:
        if f in folders:
            flash(
                _(
                    "Move elements: destination folder is included in moved "
                    "elements. Moved nothing."
                ),
                "error",
            )
            return redirect(url_for(folder))
        f = f.parent

    exist_in_dest = objects_which_exist_in_dest(objects, target_folder)
    if exist_in_dest:
        # items existing in destination: cancel operation
        db.session.rollback()
        msg = _(
            "Move elements: canceled, some elements exists in destination "
            "folder: {elements}"
        )
        elements = ", ".join(f'"{i.title}"' for i in exist_in_dest)
        flash(msg.format(elements=elements), "error")
        return redirect(current_folder_url)

    db.session.commit()

    msg_f = (
        _n("1 folder", "{count} folders", count_f) if count_f else _("0 folder")
    ).format(count=count_f)

    msg_d = (
        _n("1 document", "{count} documents", count_d) if count_d else _("0 document")
    ).format(count=count_d)

    msg = _("{folders} and {documents} moved to {target}").format(
        folders=msg_f, documents=msg_d, target=target_folder.title
    )
    flash(msg, "success")

    return redirect(url_for(folder))
Exemple #18
0
def move_multiple(folder):
    # type: (Folder) -> Response
    folders, docs = get_selected_objects(folder)
    objects = folders + docs

    count_f = len(folders)
    count_d = len(docs)
    current_folder_url = url_for(folder)

    if not (count_f + count_d):
        flash(_("Move elements: no elements selected."), "info")
        return redirect(current_folder_url)

    try:
        target_folder_id = int(request.form.get("target-folder"))
    except ValueError:
        flash(_("Move elements: no destination folder selected. Aborted."),
              "error")
        return redirect(current_folder_url)

    target_folder = repository.get_folder_by_id(target_folder_id)

    if folder == target_folder:
        flash(
            _("Move elements: source and destination folder are identical,"
              " nothing done."),
            "error",
        )
        return redirect(current_folder_url)

    if not security.has_permission(current_user, "write", folder,
                                   inherit=True):
        # this should not happen: this is just defensive programming
        flash(_("You are not allowed to move elements from this folder"),
              "error")
        return redirect(current_folder_url)

    if not security.has_permission(
            current_user, "write", target_folder, inherit=True):
        flash(
            _('You are not allowed to write in folder "{folder}"').format(
                folder=target_folder.title),
            "error",
        )
        return redirect(current_folder_url)

    for item in objects:
        # FIXME: maybe too brutal
        check_write_access(item)

    # verify we are not trying to move a folder inside itself or one of its
    # descendants
    f = target_folder
    while f:
        if f in folders:
            flash(
                _("Move elements: destination folder is included in moved "
                  "elements. Moved nothing."),
                "error",
            )
            return redirect(url_for(folder))
        f = f.parent

    exist_in_dest = objects_which_exist_in_dest(objects, target_folder)
    if exist_in_dest:
        # items existing in destination: cancel operation
        db.session.rollback()
        msg = _("Move elements: canceled, some elements exists in destination "
                "folder: {elements}")
        elements = ", ".join('"{}"'.format(i.title) for i in exist_in_dest)
        flash(msg.format(elements=elements), "error")
        return redirect(current_folder_url)

    db.session.commit()

    msg_f = (_n("1 folder", "{count} folders", count_f)
             if count_f else _("0 folder")).format(count=count_f)

    msg_d = (_n("1 document", "{count} documents", count_d)
             if count_d else _("0 document")).format(count=count_d)

    msg = _("{folders} and {documents} moved to {target}").format(
        folders=msg_f, documents=msg_d, target=target_folder.title)
    flash(msg, "success")

    return redirect(url_for(folder))