def test_recursive_zip(community, client, req_ctx): user = community.test_user with client_login(client, user): data = {"action": "new", "title": "my folder"} folder = community.folder url = url_for( "documents.folder_post", community_id=community.slug, folder_id=folder.id ) response = client.post(url, data=data) assert response.status_code == 302 my_folder = folder.children[0] title = "onepage.pdf" content_type = "application/pdf" data = {"file": (open_file(title), title, content_type), "action": "upload"} url = url_for( "documents.folder_post", community_id=community.slug, folder_id=my_folder.id ) response = client.post(url, data=data) assert response.status_code == 302 data = { "action": "download", "object-selected": ["cmis:folder:%d" % my_folder.id], } url = url_for( "documents.folder_post", community_id=community.slug, folder_id=folder.id ) response = client.post(url, data=data) assert response.status_code == 200 assert response.content_type == "application/zip" zipfile = ZipFile(BytesIO(response.data)) assert zipfile.namelist() == ["my folder/" + title]
def page_compare(): title = request.args["title"].strip() try: page = get_page_by_title(title) except NoResultFound: return redirect( url_for(".page_edit", title=title, community_id=g.community.slug) ) revisions = page.revisions revisions = sorted(revisions, key=lambda x: x.number) revs_to_compare = [] for arg in request.args: if arg.startswith("rev"): revs_to_compare.append(int(arg[3:])) if len(revs_to_compare) != 2: flash(_("You must check exactly 2 revisions."), "error") url = url_for(".page_changes", title=title, community_id=g.community.slug) return redirect(url) revs_to_compare.sort() from_rev = revisions[revs_to_compare[0]] to_rev = revisions[revs_to_compare[1]] assert from_rev.number == revs_to_compare[0] assert to_rev.number == revs_to_compare[1] from_lines = from_rev.body_src.splitlines(1) to_lines = to_rev.body_src.splitlines(1) differ = difflib.Differ(charjunk=difflib.IS_CHARACTER_JUNK) diff = differ.compare(from_lines, to_lines) diff = [line for line in diff if not line.startswith("?")] actions.context["object"] = page ctx = {"page": page, "diff": diff, "rev1": from_rev, "rev2": to_rev} return render_template("wiki/compare.html", **ctx)
def test_zip(community, client, req_ctx): user = community.test_user with client_login(client, user): title = "onepage.pdf" content_type = "application/pdf" data = { "file": (open_file(title), title, content_type), "action": "upload" } folder = community.folder url = url_for("documents.folder_post", community_id=community.slug, folder_id=folder.id) response = client.post(url, data=data) assert response.status_code == 302 doc = folder.children[0] data = { "action": "download", "object-selected": ["cmis:document:%d" % doc.id] } url = url_for("documents.folder_post", community_id=community.slug, folder_id=folder.id) response = client.post(url, data=data) assert response.status_code == 200 assert response.content_type == "application/zip" zipfile = ZipFile(BytesIO(response.data)) assert [zipfile.namelist()[0]] == [title]
def test_zip(self): with self.client_login(self.user.email, password='******'): title = u"onepage.pdf" content_type = "application/pdf" data = { 'file': (self.open_file(title), title, content_type), 'action': 'upload', } folder = self.community.folder url = url_for( "documents.folder_post", community_id=self.community.slug, folder_id=folder.id) response = self.client.post(url, data=data) self.assert_302(response) doc = folder.children[0] data = { 'action': 'download', 'object-selected': ["cmis:document:%d" % doc.id] } url = url_for( "documents.folder_post", community_id=self.community.slug, folder_id=folder.id) response = self.client.post(url, data=data) self.assert_200(response) assert response.content_type == 'application/zip' zipfile = ZipFile(BytesIO(response.data)) assert zipfile.namelist() == [title]
def message(self, ignore_community=False): try: # another quick&dirty approach for now. FIXME later. entry = self._model object_class = entry.object_type.split(".")[-1] object_class_localized = _(object_class) ctx = {} ctx["verb"] = entry.verb ctx["object_name"] = entry.object.name or getattr( entry.object, "title", "???") ctx["object_url"] = url_for(entry.object) ctx["object_type"] = object_class_localized ctx["object"] = OBJ_TEMPLATE.render(**ctx) if entry.target: ctx["target_name"] = entry.target.name ctx["target_url"] = url_for(entry.target) ctx["target"] = OBJ_TEMPLATE.render( object_name=ctx["target_name"], object_url=ctx["target_url"]) msg = MESSAGES.get((entry.verb, entry.object.__class__)) if msg: msg = msg.format(**ctx) if entry.target and not ignore_community: msg += " " + _("in the community {target}.").format(**ctx) else: msg += "." elif entry.verb == "post": msg = _("has posted an object of type {object_type} " 'called "{object}"').format(**ctx) if entry.target and not ignore_community: msg += " " + _("in the community {target}.").format(**ctx) else: msg += "." elif entry.verb == "join": msg = _("has joined the community {object}.").format(**ctx) elif entry.verb == "leave": msg = _("has left the community {object}.").format(**ctx) elif entry.verb == "update": msg = _("has updated {object_type} {object}.").format(**ctx) else: msg = _('has done action "{verb}" on object "{object}".' ).format(**ctx) return Markup(msg) except BaseException: logger.exception("Exception while presenting activity message") raise
def message(self, ignore_community=False): try: # another quick&dirty approach for now. FIXME later. entry = self._model object_class = entry.object_type.split('.')[-1] object_class_localized = _(object_class) ctx = {} ctx['verb'] = entry.verb ctx['object_name'] = entry.object.name or getattr( entry.object, 'title', "???") ctx['object_url'] = url_for(entry.object) ctx['object_type'] = object_class_localized ctx['object'] = OBJ_TEMPLATE.render(**ctx) if entry.target: ctx['target_name'] = entry.target.name ctx['target_url'] = url_for(entry.target) ctx['target'] = OBJ_TEMPLATE.render( object_name=ctx['target_name'], object_url=ctx['target_url']) msg = MESSAGES.get((entry.verb, entry.object.__class__)) if msg: msg = msg.format(**ctx) if entry.target and not ignore_community: msg += " " + _('in the community {target}.').format(**ctx) else: msg += "." elif entry.verb == 'post': msg = _('has posted an object of type {object_type} ' 'called "{object}"').format(**ctx) if entry.target and not ignore_community: msg += " " + _('in the community {target}.').format(**ctx) else: msg += "." elif entry.verb == 'join': msg = _('has joined the community {object}.').format(**ctx) elif entry.verb == 'leave': msg = _('has left the community {object}.').format(**ctx) elif entry.verb == 'update': msg = _('has updated {object_type} {object}.').format(**ctx) else: msg = _('has done action "{verb}" on object "{object}".' ).format(**ctx) return Markup(msg) except: logger.exception('Exception while presenting activity message') raise
def get(self): # FIXME: use widgets.AjaxMainTableView instead datatable_options = { 'sDom': 'lfFrtip', 'aaSorting': [ [0, u'asc'], ], 'aoColumns': [ dict(asSorting=['asc', 'desc']), dict(bSortable=False), dict(bSortable=False), ], 'bFilter': True, 'oLanguage': { 'sSearch': _("Filter records:"), 'sPrevious': _("Previous"), 'sNext': _("Next"), 'sInfo': _("Showing _START_ to _END_ of _TOTAL_ entries"), 'sInfoFiltered': _("(filtered from _MAX_ total entries)"), 'sAddAdvancedFilter': _("Add a filter"), }, 'bStateSave': False, 'bPaginate': True, 'sPaginationType': "bootstrap", 'bLengthChange': False, 'iDisplayLength': 30, 'bProcessing': True, 'bServerSide': True, 'sAjaxSource': url_for('.groups_json_list'), } return render_template('admin/groups.html', next=next, datatable_options=datatable_options)
def get(self): # FIXME: use widgets.AjaxMainTableView instead datatable_options = { "sDom": "lfFritip", "aaSorting": [[1, u"asc"]], "aoColumns": [ dict(bSortable=False), dict(asSorting=["asc", "desc"]), dict(asSorting=["asc", "desc"]), dict(bSortable=False), dict(bSortable=False), dict(bSortable=False), dict(asSorting=["asc", "desc"]), ], "bFilter": True, "oLanguage": { "sSearch": _("Filter records:"), "sPrevious": _("Previous"), "sNext": _("Next"), "sInfo": _("Showing _START_ to _END_ of _TOTAL_ entries"), "sInfoFiltered": _("(filtered from _MAX_ total entries)"), "sAddAdvancedFilter": _("Add a filter"), }, "bStateSave": False, "bPaginate": True, "sPaginationType": "bootstrap", "bLengthChange": False, "iDisplayLength": 30, "bProcessing": True, "bServerSide": True, "sAjaxSource": url_for(".users_json_list"), } return render_template("admin/users.html", next=next, datatable_options=datatable_options)
def render(self): render = render_template_string e = self.entry user = render(self._USER_FMT, user=e.user) self.entity_deleted = e.entity is None entity_html = e.entity_name if not self.entity_deleted: try: entity_url = url_for(e.entity) except (BuildError, ValueError): pass else: entity_html = Markup(render( u'<a href="{{ url }}">{{ entity.path or entity.name }}</a>', url=entity_url, entity=e.entity)) if e.type == 0: msg = _(u'{user} created {entity_type} {entity_id} "{entity}"') elif e.related or e.op == 1: msg = _(u'{user} made changes on {entity_type} {entity_id} "{entity}"') elif e.op == 2: msg = _(u'{user} has deleted {entity_type}: {entity_id} "{entity}"') else: raise Exception("Bad entry type: {}".format(e.type)) self.msg = Markup(msg.format(user=user, entity=entity_html, entity_type=e.entity_type.rsplit('.', 1)[-1], entity_id=e.entity_id,)) tmpl = get_template_attribute('admin/_macros.html', 'm_audit_entry') return tmpl(self)
def home(): """Home page. Actually there is no home page, so we redirect to the most appropriate place. """ return redirect(url_for("social.home"))
def get(self): # FIXME: use widgets.AjaxMainTableView instead datatable_options = { "sDom": "lfFritip", "aaSorting": [[1, "asc"]], "aoColumns": [ { "bSortable": False }, { "asSorting": ["asc", "desc"] }, { "asSorting": ["asc", "desc"] }, { "bSortable": False }, { "bSortable": False }, { "bSortable": False }, { "asSorting": ["asc", "desc"] }, ], "bFilter": True, "oLanguage": { "sSearch": _("Filter records:"), "sPrevious": _("Previous"), "sNext": _("Next"), "sInfo": _("Showing _START_ to _END_ of _TOTAL_ entries"), "sInfoFiltered": _("(filtered from _MAX_ total entries)"), "sAddAdvancedFilter": _("Add a filter"), }, "bStateSave": False, "bPaginate": True, "sPaginationType": "bootstrap", "bLengthChange": False, "iDisplayLength": 30, "bProcessing": True, "bServerSide": True, "sAjaxSource": url_for(".users_json_list"), } return render_template("admin/users.html", next=next, datatable_options=datatable_options)
def data(self, *args, **kw) -> Dict: security = get_service("security") length = int(kw.get("iDisplayLength", 0)) start = int(kw.get("iDisplayStart", 0)) sort_dir = kw.get("sSortDir_0", "asc") echo = int(kw.get("sEcho", 0)) search = kw.get("sSearch", "").replace("%", "").strip().lower() end = start + length # pyre-fixme[16]: `Group` has no attribute `query`. query = Group.query.options(sa.orm.noload("*")) total_count = query.count() if search: # TODO: gérer les accents query = query.filter( func.lower(Group.name).like("%" + search + "%")) count = query.count() columns = [func.lower(Group.name)] direction = asc if sort_dir == "asc" else desc order_by = list(map(direction, columns)) # sqlite does not support 'NULLS FIRST|LAST' in ORDER BY clauses # pyre-fixme[16]: `Group` has no attribute `__mapper__`. engine = query.session.get_bind(Group.__mapper__) if engine.name != "sqlite": order_by[0] = nullslast(order_by[0]) query = query.order_by(*order_by).add_columns(Group.members_count) groups = query.slice(start, end).all() data = [] for group, members_count in groups: # TODO: this should be done on the browser. group_url = url_for(".groups_group", group_id=group.id) name = html.escape(group.name or "") # pyre-fixme[16]: `Service` has no attribute `get_roles`. roles = [r for r in security.get_roles(group) if r.assignable] columns = [ f'<a href="{group_url}">{name}</a>', str(members_count or 0), render_template_string( """{%- for role in roles %} <span class="badge badge-default">{{ role }}</span> {%- endfor %}""", roles=roles, ), "\u2713" if group.public else "", ] data.append(columns) return { "sEcho": echo, "iTotalRecords": total_count, "iTotalDisplayRecords": count, "aaData": data, }
def data(self, *args, **kw): security = get_service('security') length = int(kw.get("iDisplayLength", 0)) start = int(kw.get("iDisplayStart", 0)) sort_dir = kw.get("sSortDir_0", "asc") echo = int(kw.get("sEcho", 0)) search = kw.get("sSearch", "").replace("%", "").strip().lower() end = start + length query = Group.query \ .options(sa.orm.noload('*')) total_count = query.count() if search: # TODO: gérer les accents query = query.filter( func.lower(Group.name).like("%" + search + "%"), ) count = query.count() columns = [func.lower(Group.name)] direction = asc if sort_dir == 'asc' else desc order_by = list(map(direction, columns)) # sqlite does not support 'NULLS FIRST|LAST' in ORDER BY clauses engine = query.session.get_bind(Group.__mapper__) if engine.name != 'sqlite': order_by[0] = nullslast(order_by[0]) query = query.order_by(*order_by) \ .add_columns(Group.members_count) groups = query.slice(start, end).all() data = [] for group, members_count in groups: # TODO: this should be done on the browser. group_url = url_for(".groups_group", group_id=group.id) name = escape(getattr(group, "name") or "") roles = [r for r in security.get_roles(group) if r.assignable] columns = [ '<a href="{url}">{name}</a>'.format(url=group_url, name=name), text_type(members_count or 0), render_template_string( '''{%- for role in roles %} <span class="badge badge-default">{{ role }}</span> {%- endfor %}''', roles=roles, ), '\u2713' if group.public else '', ] data.append(columns) return { "sEcho": echo, "iTotalRecords": total_count, "iTotalDisplayRecords": count, "aaData": data, }
def page_delete(): title = request.form["title"].strip() try: page = get_page_by_title(title) except NoResultFound: flash(_("This page doesn't exist"), "error") return redirect(url_for(".index", community_id=g.community.slug)) db.session.delete(page) app = unwrap(current_app) community = g.community._model activity.send(app, actor=current_user, verb="delete", object=page, target=community) db.session.commit() flash(_("Page %(title)s deleted.", title=title)) return redirect(url_for(".index", community_id=g.community.slug))
def render(self): render = render_template_string e = self.entry manager = render( u'<img class="avatar" ' u'src="{{ user_photo_url(user=e.manager, size=16) }}" alt="" />' u'<a href="''{{ url_for("social.user", user_id=e.manager.id) }}">' u'{{ e.manager.name }}</a>', e=e) if self.entry.user: principal = render(self._USER_FMT, user=self.entry.user) elif self.entry.group: principal = render(self._GROUP_FMT, group=self.entry.group) else: principal = u'' entity = u'' if e.object_id: entity_url = None entity_name = e.object_name if e.object: entity_name = getattr(e.object, 'path', e.object.name) entity_url = url_for(e.object) entity = render( u'{%- if url %}<a href="{{ url }}">{%- endif %}' u'{{ name }}{%- if url %}</a>{%- endif %}', url=entity_url, name=entity_name) if e.op == e.SET_INHERIT: msg = _(u'{manager} has activated inheritance on {entity}') elif e.op == e.UNSET_INHERIT: msg = _(u'{manager} has deactivated inheritance on {entity}') elif e.op == e.GRANT: msg = _(u'{manager} has given role "{role}" to {principal} ' 'on {entity}') elif e.op == e.REVOKE: msg = _(u'{manager} has revoked role "{role}" from ' '{principal} on {entity}') else: raise Exception("Invalid entity op: {}".format(e.op)) else: if e.op == e.GRANT: msg = _(u'{manager} has given role "{role}" to {principal}') elif e.op == e.REVOKE: msg = _(u'{manager} has revoked role "{role}" from {principal}') else: raise Exception("Invalid entity op: {}".format(e.op)) self.msg = Markup(msg.format(manager=manager, principal=principal, role=e.role, entity=entity)) tmpl = get_template_attribute('admin/_macros.html', 'm_security_entry') return tmpl(self)
def data(self, *args, **kw): security = current_app.services['security'] length = int(kw.get("iDisplayLength", 0)) start = int(kw.get("iDisplayStart", 0)) sort_dir = kw.get("sSortDir_0", "asc") echo = int(kw.get("sEcho", 0)) search = kw.get("sSearch", "").replace("%", "").strip().lower() end = start + length q = Group.query \ .options(sa.orm.noload('*')) total_count = q.count() if search: # TODO: gérer les accents q = q.filter(func.lower(Group.name).like("%" + search + "%")) count = q.count() columns = [func.lower(Group.name)] direction = asc if sort_dir == 'asc' else desc order_by = map(direction, columns) # sqlite does not support 'NULLS FIRST|LAST' in ORDER BY clauses engine = q.session.get_bind(Group.__mapper__) if engine.name != 'sqlite': order_by[0] = nullslast(order_by[0]) q = q.order_by(*order_by) \ .add_columns(Group.members_count) groups = q.slice(start, end).all() data = [] for group, members_count in groups: # TODO: this should be done on the browser. group_url = url_for(".groups_group", group_id=group.id) name = escape(getattr(group, "name") or "") roles = [r for r in security.get_roles(group) if r.assignable] columns = [] columns.append( u'<a href="{url}">{name}</a>'.format(url=group_url, name=name) ) columns.append(unicode(members_count or 0)) columns.append(render_template_string( u'''{%- for role in roles %} <span class="badge badge-default">{{ role }}</span> {%- endfor %}''', roles=roles)) columns.append(u'\u2713' if group.public else u'') data.append(columns) return { "sEcho": echo, "iTotalRecords": total_count, "iTotalDisplayRecords": count, "aaData": data, }
def data(self, *args, **kw): security = get_service("security") length = int(kw.get("iDisplayLength", 0)) start = int(kw.get("iDisplayStart", 0)) sort_dir = kw.get("sSortDir_0", "asc") echo = int(kw.get("sEcho", 0)) search = kw.get("sSearch", "").replace("%", "").strip().lower() end = start + length query = Group.query.options(sa.orm.noload("*")) total_count = query.count() if search: # TODO: gérer les accents query = query.filter(func.lower(Group.name).like("%" + search + "%")) count = query.count() columns = [func.lower(Group.name)] direction = asc if sort_dir == "asc" else desc order_by = list(map(direction, columns)) # sqlite does not support 'NULLS FIRST|LAST' in ORDER BY clauses engine = query.session.get_bind(Group.__mapper__) if engine.name != "sqlite": order_by[0] = nullslast(order_by[0]) query = query.order_by(*order_by).add_columns(Group.members_count) groups = query.slice(start, end).all() data = [] for group, members_count in groups: # TODO: this should be done on the browser. group_url = url_for(".groups_group", group_id=group.id) name = html.escape(group.name or "") roles = [r for r in security.get_roles(group) if r.assignable] columns = [ f'<a href="{group_url}">{name}</a>', str(members_count or 0), render_template_string( """{%- for role in roles %} <span class="badge badge-default">{{ role }}</span> {%- endfor %}""", roles=roles, ), "\u2713" if group.public else "", ] data.append(columns) return { "sEcho": echo, "iTotalRecords": total_count, "iTotalDisplayRecords": count, "aaData": data, }
def page_source(): title = request.args['title'].strip() try: page = get_page_by_title(title) except NoResultFound: return redirect( url_for(".page_edit", title=title, community_id=g.community.slug)) actions.context['object'] = page return render_template('wiki/source.html', page=page)
def test_home(self): with self.client_login(self.user.email, password='******'): response = self.get( url_for( 'documents.index', community_id=self.community.slug)) self.assert_status(response, 302) self.assertEqual( response.headers['Location'], u'http://localhost/communities/{}/docs/folder/{}' u''.format(self.community.slug, self.folder.id),)
def test_home(app, client, db, community, req_ctx): folder = community.folder user = community.test_user with client_login(client, user): response = client.get(url_for("documents.index", community_id=community.slug)) assert response.status_code == 302 path = path_from_url(response.location) expected = f"/communities/{community.slug}/docs/folder/{folder.id}" assert path == expected
def page_source(): title = request.args["title"].strip() try: page = get_page_by_title(title) except NoResultFound: return redirect( url_for(".page_edit", title=title, community_id=g.community.slug) ) actions.context["object"] = page return render_template("wiki/source.html", page=page)
def get_body_document(object): # type: (Document) -> Markup body = bleach.clean(object.body_html, tags=[], strip=True) body = Markup(body).unescape() if len(body) > 400: body = body[0:400] + "…" body = render_template_string(DOCUMENT_BODY_TEMPLATE, object_url=url_for(object), body=body, post=object) return Markup(body)
def page_changes(): title = request.args['title'].strip() try: page = get_page_by_title(title) except NoResultFound: return redirect( url_for(".page_edit", title=title, community_id=g.community.slug)) revisions = page.revisions revisions = sorted(revisions, key=lambda x: -x.number) actions.context['object'] = page return render_template('wiki/changes.html', page=page, revisions=revisions)
def page_changes(): title = request.args["title"].strip() try: page = get_page_by_title(title) except NoResultFound: url = url_for(".page_edit", title=title, community_id=g.community.slug) return redirect(url) revisions = page.revisions revisions = sorted(revisions, key=lambda x: -x.number) actions.context["object"] = page return render_template("wiki/changes.html", page=page, revisions=revisions)
def get_body_thread(object): # type: (Thread) -> Markup body = bleach.clean(object.posts[0].body_html, tags=[], strip=True) body = Markup(body).unescape() if len(body) > 400: body = body[0:400] + "…" body = render_template_string(POST_BODY_TEMPLATE, object_url=url_for(object), body=body, post=object.posts[0]) return Markup(body)
def page_compare(): title = request.args['title'].strip() try: page = get_page_by_title(title) except NoResultFound: return redirect( url_for(".page_edit", title=title, community_id=g.community.slug)) revisions = page.revisions revisions = sorted(revisions, key=lambda x: x.number) revs_to_compare = [] for arg in request.args: if arg.startswith("rev"): revs_to_compare.append(int(arg[3:])) if len(revs_to_compare) != 2: flash(_(u"You must check exactly 2 revisions."), "error") return redirect( url_for(".page_changes", title=title, community_id=g.community.slug)) revs_to_compare.sort() from_rev = revisions[revs_to_compare[0]] to_rev = revisions[revs_to_compare[1]] assert from_rev.number == revs_to_compare[0] assert to_rev.number == revs_to_compare[1] from_lines = from_rev.body_src.splitlines(1) to_lines = to_rev.body_src.splitlines(1) differ = difflib.Differ(charjunk=difflib.IS_CHARACTER_JUNK) diff = differ.compare(from_lines, to_lines) diff = [line for line in diff if not line.startswith("?")] actions.context['object'] = page return render_template( 'wiki/compare.html', page=page, diff=diff, rev1=from_rev, rev2=to_rev, )
def test_home(app, client, db, community, req_ctx): folder = community.folder user = community.test_user with client_login(client, user): response = client.get( url_for("documents.index", community_id=community.slug)) assert response.status_code == 302 path = path_from_url(response.location) expected = "/communities/{}/docs/folder/{}".format( community.slug, folder.id) assert path == expected
def page_delete(): title = request.form['title'].strip() try: page = get_page_by_title(title) except NoResultFound: flash(_(u"This page doesn't exist"), "error") return redirect(url_for(".index", community_id=g.community.slug)) db.session.delete(page) app = current_app._get_current_object() community = g.community._model activity.send(app, actor=g.user, verb="delete", object=page, target=community) db.session.commit() flash(_(u"Page %(title)s deleted.", title=title)) return redirect(url_for(".index", community_id=g.community.slug))
def init_object(self, args, kwargs): args, kwargs = BasePageView.init_object(self, args, kwargs) if not self.obj: title = kwargs["title"] if title == "Home": self.obj = create_home_page() else: url = url_for(".page_edit", title=title, community_id=g.community.slug) return redirect(url) actions.context["object"] = self.obj viewtracker.record_hit(entity=self.obj, user=current_user) return args, kwargs
def __html__(self): endpoint = self.endpoint if callable(endpoint): endpoint = endpoint() url_args = self.get_url_args() if self.url_args_callback is not None: url_args = self.url_args_callback(self, url_args) return self.template.render(url=url_for(endpoint, **url_args), width=self.width, height=self.height, css=self.css)
def _test_upload( community, client, title, content_type, test_preview=True, assert_preview_available=True, ): data = {"file": (open_file(title), title, content_type), "action": "upload"} folder = community.folder url = url_for( "documents.folder_post", community_id=community.slug, folder_id=folder.id ) response = client.post(url, data=data) assert response.status_code == 302 doc = folder.children[0] assert doc.title == title url = url_for("documents.document_view", community_id=community.slug, doc_id=doc.id) response = client.get(url) assert response.status_code == 200 url = url_for( "documents.document_download", community_id=community.slug, doc_id=doc.id ) response = client.get(url) assert response.status_code == 200 assert response.headers["Content-Type"] == content_type content = open_file(title).read() assert response.data == content if test_preview: url = url_for( "documents.document_preview_image", community_id=community.slug, doc_id=doc.id, size=500, ) response = client.get(url) if assert_preview_available: assert response.status_code == 200 assert response.headers["Content-Type"] == "image/jpeg" else: # redirect to 'missing image' assert response.status_code == 302 assert response.headers["Cache-Control"] == "no-cache" url = url_for( "documents.document_delete", community_id=community.slug, doc_id=doc.id ) response = client.post(url) assert response.status_code == 302 url = url_for("documents.document_view", community_id=community.slug, doc_id=doc.id) response = client.get(url) assert response.status_code == 404
def __html__(self): endpoint = self.endpoint if callable(endpoint): endpoint = endpoint() url_args = self.get_url_args() if self.url_args_callback is not None: url_args = self.url_args_callback(self, url_args) return self.template.render( url=url_for(endpoint, **url_args), width=self.width, height=self.height, css=self.css)
def init_object(self, args, kwargs): args, kwargs = BasePageView.init_object(self, args, kwargs) if not self.obj: title = kwargs['title'] if title == u'Home': self.obj = create_home_page() else: return redirect( url_for(".page_edit", title=title, community_id=g.community.slug)) actions.context['object'] = self.obj return args, kwargs
def init_object(self, args, kwargs): title = kwargs['title'] = request.args['title'].strip() if title: try: self.obj = get_page_by_title(title) except NoResultFound: if title == u'Home': self.obj = create_home_page() else: flash( _(u"This page doesn't exit. You must create it first." ), "warning") self.redirect( url_for(".page_new", title=title, community_id=g.community.slug)) actions.context['object'] = self.obj return args, kwargs
def attachment_delete(): title = request.args['title'].strip() attachment_id = int(request.args['attachment']) try: page = get_page_by_title(title) except NoResultFound: raise NotFound() attachment = WikiPageAttachment.query.get(attachment_id) assert attachment is not None assert attachment.wikipage is page if request.form.get('action') == 'delete': name = attachment.name db.session.delete(attachment) db.session.commit() flash(_(u'Attachment "{name}" has been deleted').format(name=name)) return redirect(url_for(page))
def attachment_delete(): title = request.args["title"].strip() attachment_id = int(request.args["attachment"]) try: page = get_page_by_title(title) except NoResultFound: raise NotFound() attachment = WikiPageAttachment.query.get(attachment_id) assert attachment is not None assert attachment.wikipage is page if request.form.get("action") == "delete": name = attachment.name db.session.delete(attachment) db.session.commit() flash(_('Attachment "{name}" has been deleted').format(name=name)) return redirect(url_for(page))
def init_object(self, args, kwargs): title = kwargs["title"] = request.args["title"].strip() if title: try: self.obj = get_page_by_title(title) except NoResultFound: if title == "Home": self.obj = create_home_page() else: flash( _("This page doesn't exit. You must create it first."), "warning", ) url = url_for( ".page_new", title=title, community_id=g.community.slug ) self.redirect(url) actions.context["object"] = self.obj return args, kwargs
def login_required(): """Before request handler to ensure login is required on any view.""" if current_app.config.get("NO_LOGIN"): return if request.path.startswith(current_app.static_url_path): return if request.url_rule and request.url_rule.endpoint == "geodata.static": # geodata blueprint assets return if request.blueprint in ("login", "first_login", "projects", "notifications"): return if request.blueprint == "_debug_toolbar" and current_app.debug: return if not current_user.is_authenticated: return redirect(url_for("login.login_form", next=request.url))
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))
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))
def test_zip_upload_uncompress(self): folder = Folder(title=u'folder 1', parent=self.community.folder) self.session.add(folder) self.session.flush() folder = self.community.folder files = [] files.append((BytesIO(b'A document'), u'existing-doc', 'text/plain')) files.append((self.open_file('content.zip'), u'content.zip', 'application/zip')) data = {'file': files, 'action': 'upload', 'uncompress_files': True} url = url_for( "documents.folder_post", community_id=self.community.slug, folder_id=folder.id) with self.client_login(self.user.email, password='******'): response = self.client.post(url, data=data) expected = {u'existing-doc', u'folder 1', u'existing-doc-1'} self.assert_status(response, 302) assert expected == {f.title for f in folder.children} expected = {u'folder 1', u'existing-doc-1'} assert expected == {f.title for f in folder.subfolders}
def render(self): render = render_template_string e = self.entry user = render(self._USER_FMT, user=e.user) self.entity_deleted = e.entity is None entity_html = e.entity_name if not self.entity_deleted: try: entity_url = url_for(e.entity) except (BuildError, ValueError): pass else: entity_html = Markup( render( '<a href="{{ url }}">{{ entity.path or entity.name }}</a>', url=entity_url, entity=e.entity, ), ) if e.type == 0: msg = _('{user} created {entity_type} {entity_id} "{entity}"') elif e.related or e.op == 1: msg = _( '{user} made changes on {entity_type} {entity_id} "{entity}"') elif e.op == 2: msg = _('{user} has deleted {entity_type}: {entity_id} "{entity}"') else: raise Exception("Bad entry type: {}".format(e.type)) self.msg = Markup( msg.format( user=user, entity=entity_html, entity_type=e.entity_type.rsplit('.', 1)[-1], entity_id=e.entity_id, ), ) tmpl = get_template_attribute('admin/_macros.html', 'm_audit_entry') return tmpl(self)
def test_zip_upload_uncompress(community, db, client, req_ctx): subfolder = Folder(title="folder 1", parent=community.folder) db.session.add(subfolder) db.session.flush() folder = community.folder files = [] files.append((BytesIO(b"A document"), "existing-doc", "text/plain")) files.append((open_file("content.zip"), "content.zip", "application/zip")) data = {"file": files, "action": "upload", "uncompress_files": True} url = url_for("documents.folder_post", community_id=community.slug, folder_id=folder.id) user = community.test_user with client_login(client, user): response = client.post(url, data=data) assert response.status_code == 302 expected = {"existing-doc", "folder 1", "existing-doc-1"} assert expected == {f.title for f in folder.children} expected = {"folder 1", "existing-doc-1"} assert expected == {f.title for f in folder.subfolders}
def test_zip_upload_uncompress(community, db, client, req_ctx): subfolder = Folder(title="folder 1", parent=community.folder) db.session.add(subfolder) db.session.flush() folder = community.folder files = [] files.append((BytesIO(b"A document"), "existing-doc", "text/plain")) files.append((open_file("content.zip"), "content.zip", "application/zip")) data = {"file": files, "action": "upload", "uncompress_files": True} url = url_for( "documents.folder_post", community_id=community.slug, folder_id=folder.id ) user = community.test_user with client_login(client, user): response = client.post(url, data=data) assert response.status_code == 302 expected = {"existing-doc", "folder 1", "existing-doc-1"} assert expected == {f.title for f in folder.children} expected = {"folder 1", "existing-doc-1"} assert expected == {f.title for f in folder.subfolders}
def index_url(self): return url_for('.users')
def view_url(self): return url_for('.groups_group', group_id=self.obj.id)
def index_url(self): return url_for('.groups')
def index(): return redirect(url_for(".page", title="Home", community_id=g.community.slug))
def index_url(self): return url_for(".index", community_id=g.community.slug)
def __unicode__(self): return unicode(url_for(self.name, *self.args, **self.get_kwargs()))
def object_url(self): return url_for(self._model.object)
def redirect_if_no_change(self): form = self.form if all(f.data == f.object_data for f in (form.title, form.body_src)): flash(_("You didn't make any change to this page.")) return self.redirect(url_for(self.obj))
def view_url(self): return url_for( self.view_endpoint, community_id=g.community.slug, title=self.obj.title )
def home(): """ Home page. Actually there is no home page, so for this demo we redirect to the most appropriate place. """ return redirect(url_for("admin.settings"))
def test_document_send_by_mail(app, community, client, req_ctx): mail = app.extensions["mail"] folder = community.folder user = community.test_user with client_login(client, user): # upload files for filename in ("ascii title.txt", "utf-8 est arrivé!.txt"): content_type = "text/plain" data = { "file": (BytesIO(b"file content"), filename, content_type), "action": "upload", } url = url_for( "documents.folder_post", community_id=community.slug, folder_id=folder.id, ) client.post(url, data=data) ascii_doc = folder.children[0] unicode_doc = folder.children[1] def get_send_url(doc_id): return url_for( "documents.document_send", community_id=community.slug, doc_id=doc_id ) # mail ascii filename with mail.record_messages() as outbox: url = get_send_url(ascii_doc.id) response = client.post( url, data={"recipient": "*****@*****.**", "message": "Voilà un fichier"}, ) assert response.status_code == 302 assert len(outbox) == 1 msg = outbox[0] assert msg.subject == "[Abilian Test] Unknown sent you a file" assert msg.recipients == ["*****@*****.**"] assert len(msg.attachments) == 1 attachment = first(msg.attachments) assert isinstance(attachment, flask_mail.Attachment) assert attachment.filename == "ascii title.txt" # mail unicode filename with mail.record_messages() as outbox: url = get_send_url(unicode_doc.id) response = client.post( url, data={"recipient": "*****@*****.**", "message": "Voilà un fichier"}, ) assert response.status_code == 302 assert len(outbox) == 1 msg = outbox[0] assert isinstance(msg, flask_mail.Message) assert msg.subject == "[Abilian Test] Unknown sent you a file" assert msg.recipients == ["*****@*****.**"] assert len(msg.attachments) == 1 attachment = first(msg.attachments) assert isinstance(attachment, flask_mail.Attachment) assert attachment.filename == "utf-8 est arrivé!.txt"
def data(self, *args, **kw): security = current_app.services['security'] length = int(kw.get("iDisplayLength", 0)) start = int(kw.get("iDisplayStart", 0)) sort_col = int(kw.get("iSortCol_0", 1)) sort_dir = kw.get("sSortDir_0", "asc") echo = int(kw.get("sEcho", 0)) search = kw.get("sSearch", "").replace("%", "").strip().lower() end = start + length q = User.query \ .options(sa.orm.subqueryload('groups'), sa.orm.undefer('photo'), ) \ .filter(User.id != 0) total_count = q.count() if search: # TODO: gérer les accents filter = or_(func.lower(User.first_name).like("%" + search + "%"), func.lower(User.last_name).like("%" + search + "%"), func.lower(User.email).like("%" + search + "%")) q = q.filter(filter) count = q.count() SORT_COLS = { 1: [], # [User.last_name, User.first_name] will be added anyway 2: [func.lower(User.email)], 5: [User.last_active], } columns = list(SORT_COLS.get(sort_col, [])) columns.extend([func.lower(User.last_name), func.lower(User.first_name)]) direction = asc if sort_dir == 'asc' else desc order_by = map(direction, columns) # sqlite does not support 'NULLS FIRST|LAST' in ORDER BY clauses engine = q.session.get_bind(User.__mapper__) if engine.name != 'sqlite': order_by[0] = nullslast(order_by[0]) q = q.order_by(*order_by) users = q.slice(start, end).all() data = [] MUGSHOT_SIZE = 45 for user in users: # TODO: this should be done on the browser. user_url = url_for(".users_user", user_id=user.id) mugshot = user_photo_url(user, size=MUGSHOT_SIZE) name = escape(getattr(user, "name") or "") email = escape(getattr(user, "email") or "") roles = [r for r in security.get_roles(user, no_group_roles=True) if r.assignable] columns = [] columns.append( u'<a href="{url}"><img src="{src}" width="{size}" height="{size}">' u'</a>'.format(url=user_url, src=mugshot, size=MUGSHOT_SIZE) ) columns.append( u'<a href="{url}">{name}</a>'.format(url=user_url, name=name)) columns.append( u'<a href="{url}"><em>{email}</em></a>'.format(url=user_url, email=email)) columns.append(u'\u2713' if user.can_login else u'') columns.append(render_template_string( u'''{%- for g in groups %} <span class="badge badge-default">{{ g.name }}</span> {%- endfor %}''', groups=sorted(user.groups))) columns.append(render_template_string( u'''{%- for role in roles %} <span class="badge badge-default">{{ role }}</span> {%- endfor %}''', roles=roles)) if user.last_active: last_active = format_datetime(user.last_active) else: last_active = _(u'Never logged in') columns.append(last_active) data.append(columns) return { "sEcho": echo, "iTotalRecords": total_count, "iTotalDisplayRecords": count, "aaData": data, }
def get_send_url(doc_id): return url_for( "documents.document_send", community_id=community.slug, doc_id=doc_id )