コード例 #1
0
ファイル: forms.py プロジェクト: woakes070048/abilian-sbe
class WikiPageForm(Form):
    title = StringField(label=_l(u"Title"),
                        filters=(strip, ),
                        validators=[required()])
    body_src = TextAreaField(
        label=_l("Body"),
        filters=(strip, clean_up),
        validators=[required()],
        widget=TextArea(rows=10, resizeable='vertical'),
    )

    message = StringField(label=_l("Commit message"))
    page_id = HiddenField(filters=(int_or_none, ), validators=[flaghidden()])
    last_revision_id = HiddenField(filters=(int_or_none, ),
                                   validators=[flaghidden()])

    def validate_title(self, field):
        title = field.data
        if title != field.object_data and page_exists(title):
            raise ValidationError(
                _(u"A page with this name already exists. Please use another name."
                  ))

    def validate_last_revision_id(self, field):
        val = field.data
        current = field.object_data

        if val is None or current is None:
            return

        if val != current:
            raise ValidationError(_(u'this page has been edited since'))
コード例 #2
0
ファイル: views.py プロジェクト: phonix2012/abilian-sbe
class ThreadCloseView(BaseThreadView, views.object.BaseObjectView):
    """Close / Re-open a thread."""

    methods = ["POST"]
    _VALID_ACTIONS = {"close", "reopen"}
    CLOSED_MSG = _l("The thread is now closed for edition and new "
                    "contributions.")
    REOPENED_MSG = _l("The thread is now re-opened for edition and new "
                      "contributions.")

    def prepare_args(self, args, kwargs):
        args, kwargs = super(ThreadCloseView, self).prepare_args(args, kwargs)
        action = kwargs["action"] = request.form.get("action")
        if action not in self._VALID_ACTIONS:
            raise BadRequest("Unknown action: {!r}".format(action))

        return args, kwargs

    def post(self, action=None):
        is_closed = action == "close"
        self.obj.closed = is_closed
        sa.orm.object_session(self.obj).commit()

        msg = self.CLOSED_MSG if is_closed else self.REOPENED_MSG
        flash(text_type(msg))
        return self.redirect(url_for(self.obj))
コード例 #3
0
ファイル: forms.py プロジェクト: phonix2012/abilian-sbe
class PostEditForm(BasePostForm):
    reason = StringField(
        label=_l("Reason"),
        description=_l("Description of your edit"),
        filters=(strip,),
        validators=(optional(),),
    )
コード例 #4
0
ファイル: views.py プロジェクト: phonix2012/abilian-sbe
class EventEditView(BaseEventView, views.ObjectEdit):
    POST_BUTTON = ButtonAction("form",
                               "create",
                               btn_class="primary",
                               title=_l("Post this event"))

    title = _l("Edit event")
コード例 #5
0
ファイル: views.py プロジェクト: woakes070048/abilian-sbe
class ThreadCloseView(BaseThreadView, views.object.BaseObjectView):
    """Close / Re-open a thread.
    """
    methods = ['POST']
    _VALID_ACTIONS = {u'close', u'reopen'}
    CLOSED_MSG = _l(u'The thread is now closed for edition and new '
                    u'contributions.')
    REOPENED_MSG = _l(u'The thread is now re-opened for edition and new '
                      u'contributions.')

    def prepare_args(self, args, kwargs):
        args, kwargs = super(ThreadCloseView, self).prepare_args(args, kwargs)
        action = kwargs['action'] = request.form.get('action')

        if action not in self._VALID_ACTIONS:
            raise BadRequest(u'Unknown action: {!r}'.format(action))

        return args, kwargs

    def post(self, action=None):
        is_closed = (action == u'close')
        self.obj.closed = is_closed
        sa.orm.object_session(self.obj).commit()

        msg = self.CLOSED_MSG if is_closed else self.REOPENED_MSG
        flash(text_type(msg))
        return self.redirect(url_for(self.obj))
コード例 #6
0
ファイル: forms.py プロジェクト: jsdelivrbot/abilian-core
class UserCreateForm(BaseUserAdminForm):

    password = StringField(
        _l("Password"),
        description=_l("If empty a random password will be generated."),
        widget=widgets.PasswordInput(autocomplete="off"),
    )
コード例 #7
0
ファイル: common.py プロジェクト: abilian/abilian-sbe
def activity_time_format(time, now=None):
    if not time:
        return ""

    if not now:
        now = datetime.utcnow()
    time_delta = now - time
    month_abbreviation = format_date(time, "MMM")
    days, hours, minutes, seconds = (
        time_delta.days,
        time_delta.seconds // 3600,
        time_delta.seconds // 60,
        time_delta.seconds,
    )

    if days == 0 and hours == 0 and minutes == 0:
        return "{}{}".format(seconds, _l("s"))

    if days == 0 and hours == 0:
        return "{}{}".format(minutes, _l("m"))

    if days == 0:
        return "{}{}".format(hours, _l("h"))

    if days < 30:
        return "{}{}".format(days, _l("d"))

    if time.year == now.year:
        return f"{month_abbreviation} {time.day}"

    return "{} {}".format(month_abbreviation, str(time.year))
コード例 #8
0
class GroupAdminForm(Form):
    name = StringField(_l(u'Name'), filters=(strip,), validators=[required()])
    description = StringField(_l(u'Description'), filters=(strip,))

    public = BooleanField(
        _l(u'Public'), widget=widgets.BooleanWidget(on_off_mode=True))

    roles = fields.Select2MultipleField(
        _l(u'Roles'),
        choices=lambda: [(r.name, r.label) for r in Role.assignable_roles()],)
コード例 #9
0
ファイル: forms.py プロジェクト: rmoorman/abilian-core
class AttachmentForm(Form):

    blob = FileField(_l(u'file'),
                     validators=[required()],
                     filters=[strip],
                     multiple=False)

    description = StringField(_l(u'description (optional)'), filters=[strip])

    class Meta:
        model = Attachment
        include_primary_keys = True
        assign_required = False  # for 'id': allow None, for new records
コード例 #10
0
class EditForm(ModelForm):
    label = StringField(_l(u'Label'),
                        description=_l(u'allowed tags: %(tags)s',
                                       tags=', '.join(ALLOWED_TAGS)),
                        filters=(strip, ),
                        validators=[required()])
    default = BooleanField(_l(u'Default'), default=False)
    active = BooleanField(_l(u'Active'), default=True)

    def validate_label(self, field):
        field.data = bleach.clean(field.data,
                                  tags=ALLOWED_TAGS,
                                  attributes=ALLOWED_ATTRIBUTES,
                                  strip=True)
コード例 #11
0
class BasePostForm(Form):
    message = TextAreaField(label=_l("Message"),
                            widget=RichTextWidget(allowed_tags=WIDGET_ALLOWED),
                            filters=(strip, ),
                            validators=[required()])
    attachments = FileField(label=_l('Attachments'),
                            multiple=True,
                            validators=[optional()])

    def validate_message(self, field):
        field.data = bleach.clean(field.data,
                                  tags=ALLOWED_TAGS,
                                  attributes=ALLOWED_ATTRIBUTES,
                                  styles=ALLOWED_STYLES,
                                  strip=True)
コード例 #12
0
ファイル: views.py プロジェクト: woakes070048/abilian-sbe
class PageCreate(PageEdit, ObjectCreate):
    title = _l("Create page")
    _message_success = _l(u"Wiki page successfully created.")

    get_form_kwargs = ObjectCreate.get_form_kwargs

    def init_object(self, args, kwargs):
        args, kwargs = ObjectCreate.init_object(self, args, kwargs)
        self.obj.community = g.community
        session = sa.orm.object_session(self.obj)
        if session:
            sa.orm.session.make_transient(self.obj)
            for rev in self.obj.revisions:
                sa.orm.session.make_transient(rev)
        return args, kwargs
コード例 #13
0
ファイル: views.py プロジェクト: abilian/abilian-crm-core
    def get_actions(self):
        excel_actions = []
        button = "default" if not self.EXCEL_EXPORT_RELATED else None
        endpoint = self.module.endpoint
        excel_actions.append(
            ModuleAction(
                self.module,
                "excel",
                "export_xls",
                title=_l("Export to Excel"),
                icon=FAIcon("align-justify"),
                endpoint=Endpoint(endpoint + ".export_xls"),
                button=button,
                css="datatable-export",
            )
        )

        for column_set in self.EXCEL_EXPORT_RELATED:
            excel_actions.append(
                ModuleActionGroupItem(
                    self.module,
                    "excel",
                    "export_related_" + column_set.related_attr,
                    title=column_set.export_label,
                    icon=FAIcon("align-justify"),
                    css="datatable-export",
                    endpoint=Endpoint(
                        endpoint + ".export_xls", related=column_set.related_attr
                    ),
                )
            )

        if self.EXCEL_SUPPORT_IMPORT:
            pass

        if len(excel_actions) > 1:
            excel_actions = [
                ModuleActionDropDown(
                    self.module,
                    "excel",
                    "actions",
                    title=_l("Excel"),
                    button="default",
                    items=excel_actions,
                )
            ]

        return excel_actions
コード例 #14
0
ファイル: views.py プロジェクト: woakes070048/abilian-sbe
def init_forum_values(endpoint, values):
    g.current_tab = 'forum'

    g.breadcrumb.append(
        BreadcrumbItem(label=_l(u'Conversations'),
                       url=Endpoint('forum.index',
                                    community_id=g.community.slug)))
コード例 #15
0
ファイル: views.py プロジェクト: woakes070048/abilian-sbe
class EventCreateView(BaseEventView, views.ObjectCreate):
    POST_BUTTON = ButtonAction(
        'form', 'create', btn_class='primary', title=_l('Post this event'))

    title = _l("New event")

    def after_populate_obj(self):
        if self.obj.community is None:
            self.obj.community = g.community._model

    def get_form_buttons(self, *args, **kwargs):
        return [self.POST_BUTTON, views.object.CANCEL_BUTTON]

    @property
    def activity_target(self):
        return self.obj.community
コード例 #16
0
ファイル: dashboard.py プロジェクト: isaideureka/abilian-core
class DashboardPanel(AdminPanel):
    id = 'dashboard'
    path = ''
    label = _l('Dashboard')
    icon = 'eye-open'

    def get(self):
        login_entries = LoginSession.query \
            .order_by(LoginSession.started_at.asc()) \
            .all()
        # .options(sa.orm.joinedload(LoginSession.user))
        daily, weekly, monthly = uniquelogins(login_entries)
        new_logins, total_users = newlogins(login_entries)

        stats = {
            'today': stats_since(timedelta(days=1)),
            'this_week': stats_since(timedelta(days=7)),
            'this_month': stats_since(timedelta(days=30)),
        }

        # let's format the data into NVD3 datastructures
        connections = [
            {
                'key': _('Daily'),
                'color': '#7777ff',
                'values': daily
            },
            {
                'key': _('Weekly'),
                'color': '#2ca02c',
                'values': weekly,
                'disabled': True,
            },
            {
                'key': _('Monthly'),
                'color': '#ff7f0e',
                'values': monthly,
                'disabled': True,
            },
        ]
        new_logins = [
            {
                'key': _('New'),
                'color': '#ff7f0e',
                "bar": True,
                'values': new_logins,
            },
            {
                'key': _('Total'),
                'color': '#2ca02c',
                'values': total_users
            },
        ]

        return render_template(
            "admin/dashboard.html",
            stats=stats,
            connections=connections,
            new_logins=new_logins,
        )
コード例 #17
0
    def __init__(self, *panels: Any, **kwargs: Any) -> None:
        self.app = None
        self.panels: List[AdminPanel] = []
        self._panels_endpoints: Dict[str, AdminPanel] = {}
        self.nav_paths: Dict[str, str] = {}
        self.breadcrumb_items: Dict[AdminPanel, BreadcrumbItem] = {}
        self.setup_blueprint()

        def condition(context: Dict[str, bool]) -> bool:
            return not current_user.is_anonymous and security.has_role(
                # pyre-fixme[6]: Expected `Principal` for 1st param but got
                #  `LocalProxy`.
                current_user,
                AdminRole,
            )

        self.nav_root = NavGroup(
            "admin", "root", title=_l("Admin"), endpoint=None, condition=condition
        )

        for panel in panels:
            self.register_panel(panel)

        app = kwargs.pop("app", None)
        if app is not None:
            self.init_app(app)
コード例 #18
0
ファイル: object.py プロジェクト: rmoorman/abilian-core
class ObjectCreate(ObjectEdit):
    """Create a new object.
    """
    permission = CREATE
    activity_verb = 'post'
    _message_success = _l(u"Entity successfully added")

    #: set to `True` to show 'Save and add new' button
    chain_create_allowed = False

    def __init__(self, *args, **kwargs):
        chain_create_allowed = kwargs.pop('chain_create_allowed', None)
        if chain_create_allowed is not None:
            self.chain_create_allowed = bool(chain_create_allowed)

        ObjectEdit.__init__(self, *args, **kwargs)

    def prepare_args(self, args, kwargs):
        # we must ensure that no flush() occurs and that obj is not registered in
        # session (to prevent accidental insert of an incomplete object)
        session = current_app.db.session()
        with session.no_autoflush:
            args, kwargs = super(ObjectCreate, self).prepare_args(args, kwargs)

        try:
            session.expunge(self.obj)
        except sa.exc.InvalidRequestError:
            # obj is not in session
            pass

        return args, kwargs

    def init_object(self, args, kwargs):
        self.obj = self.Model()
        return args, kwargs

    def get_form_kwargs(self):
        kw = super(ObjectCreate, self).get_form_kwargs()
        if request.method == 'GET':
            # when GET allow form prefill instead of empty/current object data
            # FIXME: filter allowed parameters on given a field flags (could be
            # 'allow_from_get'?)
            kw['formdata'] = request.args

        return kw

    def get_form_buttons(self, *args, **kwargs):
        return [CREATE_BUTTON, CHAIN_CREATE_BUTTON, CANCEL_BUTTON]

    def breadcrumb(self):
        return nav.BreadcrumbItem(label=CREATE_BUTTON.title)

    # actions
    def create(self):
        return self.edit()

    chain_create = create

    def cancel(self):
        return self.redirect_to_index()
コード例 #19
0
class ObjectDelete(ObjectEdit):
    """
  Delete object. Supports DELETE verb.
  """
    methods = ['POST']
    permission = DELETE
    activity_verb = 'delete'
    _message_success = _l(u"Entity deleted")

    init_object = BaseObjectView.init_object

    def get_form_buttons(self, *args, **kwargs):
        return [DELETE_BUTTON, CANCEL_BUTTON]

    def delete(self):
        session = current_app.db.session()
        session.delete(self.obj)
        activity.send(self,
                      actor=g.user,
                      verb="delete",
                      object=self.obj,
                      target=self.activity_target)
        session.commit()
        flash(self.message_success(), 'success')
        # FIXME: for DELETE verb response in case of success should be 200, 202
        # (accepted) or 204 (no content)
        return self.redirect_to_index()
コード例 #20
0
ファイル: views.py プロジェクト: phonix2012/abilian-sbe
class CommunityEdit(BaseCommunityView, views.ObjectEdit):
    template = "community/edit.html"
    title = _l("Edit community")
    decorators = views.ObjectEdit.decorators + (require_admin, tab("settings"))

    def breadcrumb(self):
        return BreadcrumbItem(
            label=_("Settings"),
            icon="cog",
            url=Endpoint("communities.settings", community_id=g.community.slug),
        )

    def before_populate_obj(self):
        form = self.form
        name = form.name.data
        if name != self.obj.name:
            self.obj.rename(name)

        del form.name

        type = form.type.data
        if type != self.obj.type:
            self.obj.type = type
            self.obj.update_roles_on_folder()
        del form.type

        self.linked_group = form.linked_group.data or None
        if self.linked_group:
            self.linked_group = Group.query.get(int(self.linked_group))
        del form.linked_group

    def after_populate_obj(self):
        self.obj.group = self.linked_group
コード例 #21
0
ファイル: views.py プロジェクト: woakes070048/abilian-sbe
def init_document_values(endpoint, values):
    g.current_tab = 'documents'

    g.breadcrumb.append(
        BreadcrumbItem(label=_l(u'Documents'),
                       url=Endpoint('documents.index',
                                    community_id=g.community.slug)))
コード例 #22
0
class UsersPanel(AdminPanel):
    """User administration panel."""

    id = "users"
    label = _l("Users")
    icon = "user"

    def install_additional_rules(self, add_url_rule):
        add_url_rule("/users",
                     view_func=views.JsonUsersList.as_view("json_list"))
        add_url_rule("/new", view_func=views.UserCreate.as_view("new"))
        add_url_rule("/<int:user_id>",
                     view_func=views.UserEdit.as_view("user"))

    def get(self):
        # FIXME: use widgets.AjaxMainTableView instead
        datatable_options = {
            "sDom":
            "lfFritip",
            "aaSorting": [[1, "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)
コード例 #23
0
class UserProfileEdit(ObjectEdit):

    Model = User
    Form = UserProfileForm
    pk = "user_id"
    _message_success = _l("Profile edited")

    def init_object(self, args, kwargs):
        args, kwargs = super(UserProfileEdit, self).init_object(args, kwargs)
        self.user = self.obj
        return args, kwargs

    def view_url(self):
        return url_for(".user", user_id=self.user.id)

    def edit(self):
        if not can_edit(self.user):
            return Response(status=403)
        return super(UserProfileEdit, self).edit()

    def handle_commit_exception(self, exc):
        db.session.rollback()
        if isinstance(exc, sa.exc.IntegrityError):
            log_msg = "Error saving user profile"
        else:
            log_msg = "Unexpected error while saving user profile"
        logger.error(log_msg, exc_info=True, extra={"stack": True})
        flash(_("Error occured"), "error")
        return self.redirect_to_view()
コード例 #24
0
ファイル: models.py プロジェクト: abilian/abilian-core
 def __init__(self, name, label=None, assignable=True):
     UniqueName.__init__(self, name)
     if label is None:
         label = "permission_" + str(name)
     if isinstance(label, str):
         label = _l(label)
     self.label = label
コード例 #25
0
ファイル: models.py プロジェクト: debon/abilian-core
 def __init__(self, name, label=None, assignable=True):
   UniqueName.__init__(self, name)
   if label is None:
     label = u'permission_' + unicode(name)
   if isinstance(label, unicode):
     label = _l(label)
   self.label = label
コード例 #26
0
ファイル: models.py プロジェクト: rmoorman/abilian-core
 def __init__(self, name, label=None, assignable=True):
     UniqueName.__init__(self, name)
     if label is None:
         label = u'permission_' + text_type(name)
     if isinstance(label, text_type):
         label = _l(label)
     self.label = label
コード例 #27
0
class DashboardPanel(AdminPanel):
    id = "dashboard"
    path = ""
    label = _l("Dashboard")
    icon = "eye-open"

    def get(self) -> str:
        login_entries = LoginSession.query.order_by(
            LoginSession.started_at.asc()).all()
        # .options(sa.orm.joinedload(LoginSession.user))
        daily, weekly, monthly = uniquelogins(login_entries)
        new_logins, total_users = newlogins(login_entries)

        stats = {
            "today": stats_since(timedelta(days=1)),
            "this_week": stats_since(timedelta(days=7)),
            "this_month": stats_since(timedelta(days=30)),
        }

        # let's format the data into NVD3 datastructures
        connections = [
            {
                "key": _("Daily"),
                "color": "#7777ff",
                "values": daily
            },
            {
                "key": _("Weekly"),
                "color": "#2ca02c",
                "values": weekly,
                "disabled": True,
            },
            {
                "key": _("Monthly"),
                "color": "#ff7f0e",
                "values": monthly,
                "disabled": True,
            },
        ]
        new_logins = [
            {
                "key": _("New"),
                "color": "#ff7f0e",
                "bar": True,
                "values": new_logins
            },
            {
                "key": _("Total"),
                "color": "#2ca02c",
                "values": total_users
            },
        ]

        return render_template(
            "admin/dashboard.html",
            stats=stats,
            connections=connections,
            new_logins=new_logins,
        )
コード例 #28
0
 def __init__(self, name, label=None, assignable=True):
     UniqueName.__init__(self, name)
     if label is None:
         label = "role_" + text_type(name)
     if isinstance(label, text_type):
         label = _l(label)
     self.label = label
     self.assignable = assignable
コード例 #29
0
    def entity_tags_form(self, entity, ns=None):
        """Construct a form class with a field for tags in namespace `ns`."""
        if ns is None:
            ns = self.entity_default_ns(entity)

        field = TagsField(label=_l("Tags"), ns=ns)
        cls = type("EntityNSTagsForm", (_TagsForm, ), {"tags": field})
        return cls
コード例 #30
0
ファイル: views.py プロジェクト: phonix2012/abilian-sbe
def init_forum_values(endpoint, values):
    g.current_tab = "forum"

    g.breadcrumb.append(
        BreadcrumbItem(
            label=_l("Conversations"),
            url=Endpoint("forum.index", community_id=g.community.slug),
        ))
コード例 #31
0
ファイル: extension.py プロジェクト: abilian/abilian-core
    def entity_tags_form(self, entity, ns=None):
        """Construct a form class with a field for tags in namespace `ns`."""
        if ns is None:
            ns = self.entity_default_ns(entity)

        field = TagsField(label=_l("Tags"), ns=ns)
        cls = type("EntityNSTagsForm", (_TagsForm,), {"tags": field})
        return cls
コード例 #32
0
ファイル: models.py プロジェクト: debon/abilian-core
 def __init__(self, name, label=None, assignable=True):
     UniqueName.__init__(self, name)
     if label is None:
         label = u'role_' + unicode(name)
     if isinstance(label, unicode):
         label = _l(label)
     self.label = label
     self.assignable = assignable
コード例 #33
0
ファイル: views.py プロジェクト: abilian/abilian-sbe
def init_forum_values(endpoint, values):
    g.current_tab = "forum"

    g.breadcrumb.append(
        BreadcrumbItem(
            label=_l("Conversations"),
            url=Endpoint("forum.index", community_id=g.community.slug),
        )
    )
コード例 #34
0
def init_document_values(endpoint, values):
    g.current_tab = "documents"
    g.is_manager = is_manager()

    g.breadcrumb.append(
        BreadcrumbItem(
            label=_l("Documents"),
            url=Endpoint("documents.index", community_id=g.community.slug),
        ))
コード例 #35
0
class UsersPanel(AdminPanel):
    """User administration panel."""
    id = 'users'
    label = _l(u'Users')
    icon = 'user'

    def install_additional_rules(self, add_url_rule):
        add_url_rule(
            '/users',
            view_func=views.JsonUsersList.as_view('json_list'),
        )
        add_url_rule('/new', view_func=views.UserCreate.as_view('new'))
        add_url_rule(
            '/<int:user_id>',
            view_func=views.UserEdit.as_view('user'))

    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,
        )
コード例 #36
0
ファイル: views.py プロジェクト: phonix2012/abilian-sbe
def init_wiki_values(endpoint, values):
    g.current_tab = "wiki"

    endpoint = Endpoint("wiki.index", community_id=g.community.slug)
    g.breadcrumb.append(BreadcrumbItem(label=_l("Wiki"), url=endpoint))

    title = request.args.get("title", "").strip()
    if title and title != "Home":
        url = Endpoint("wiki.page", community_id=g.community.slug, title=title)
        g.breadcrumb.append(BreadcrumbItem(label=title, url=url))
コード例 #37
0
ファイル: views.py プロジェクト: abilian/abilian-sbe
def init_document_values(endpoint, values):
    g.current_tab = "documents"
    g.is_manager = is_manager()

    g.breadcrumb.append(
        BreadcrumbItem(
            label=_l("Documents"),
            url=Endpoint("documents.index", community_id=g.community.slug),
        )
    )
コード例 #38
0
ファイル: views.py プロジェクト: abilian/abilian-sbe
def init_wiki_values(endpoint, values):
    g.current_tab = "wiki"

    endpoint = Endpoint("wiki.index", community_id=g.community.slug)
    g.breadcrumb.append(BreadcrumbItem(label=_l("Wiki"), url=endpoint))

    title = request.args.get("title", "").strip()
    if title and title != "Home":
        url = Endpoint("wiki.page", community_id=g.community.slug, title=title)
        g.breadcrumb.append(BreadcrumbItem(label=title, url=url))
コード例 #39
0
ファイル: frontend.py プロジェクト: debon/abilian-core
  def register_actions(self):
    ACTIONS = [
      ModuleAction(self, u'entity', u'create',
                   title=_l(u'Create New'), icon=FAIcon('plus'),
                   endpoint=Endpoint(self.endpoint + '.entity_new'),
                   button='default',),
    ]
    for component in self.components:
      ACTIONS.extend(component.get_actions())

    actions.register(*ACTIONS)
コード例 #40
0
ファイル: yearly.py プロジェクト: abilian/abilian-crm-core
    def get_extra_args(self, *args, **kwargs):
        from ..codegen import CodeGenerator

        generator = CodeGenerator(data=self.data["type_args"])
        year_field = IntegerField(label=_l(u"Year"))
        FormBase = generator.gen_form(self.generator.module)
        ModelField = type(self.name + "Form", (FormBase, Form), {"year": year_field})

        extra_args = super(YearlyFormField, self).get_extra_args(*args, **kwargs)
        extra_args["unbound_field"] = awbff.FormField(ModelField, default=dict)
        extra_args["population_strategy"] = "update"
        extra_args["min_entries"] = 1
        return extra_args
コード例 #41
0
ファイル: frontend.py プロジェクト: abilian/abilian-core
    def register_actions(self):
        ACTIONS = [
            ModuleAction(
                self,
                "entity",
                "create",
                title=_l("Create New"),
                icon=FAIcon("plus"),
                endpoint=Endpoint(self.endpoint + ".entity_new"),
                button="default",
            )
        ]
        for component in self.components:
            ACTIONS.extend(component.get_actions())

        actions.register(*ACTIONS)
コード例 #42
0
ファイル: blueprint.py プロジェクト: abilian/abilian-sbe
def pull_community(endpoint, values):
    """url_value_preprocessor function."""
    g.nav["active"] = "section:communities"
    g.breadcrumb.append(
        BreadcrumbItem(label=_l("Communities"), url=Endpoint("communities.index"))
    )

    try:
        slug = values.pop("community_id")
        community = Community.query.filter(Community.slug == slug).first()
        if community:
            g.community = CommunityPresenter(community)
            wall_url = Endpoint("wall.index", community_id=community.slug)
            breadcrumb_item = BreadcrumbItem(label=community.name, url=wall_url)
            g.breadcrumb.append(breadcrumb_item)
        else:
            raise NotFound()
    except KeyError:
        pass
コード例 #43
0
ファイル: extension.py プロジェクト: debon/abilian-core
  def __init__(self, *panels, **kwargs):
    self.app = None
    self.panels = []
    self._panels_endpoints = {}
    self.nav_paths = {}
    self.breadcrumb_items = {}
    self.setup_blueprint()

    self.nav_root = NavGroup(
      'admin', 'root', title=_l(u'Admin'),
      endpoint=None,
      condition=lambda context: (not current_user.is_anonymous()
                                 and security.has_role(current_user, AdminRole))
    )

    for panel in panels:
      self.register_panel(panel)

    app = kwargs.pop('app', None)
    if app is not None:
      self.init_app(app)
コード例 #44
0
ファイル: extension.py プロジェクト: abilian/abilian-core
    def __init__(self, *panels, **kwargs):
        self.app = None
        self.panels = []
        self._panels_endpoints = {}
        self.nav_paths = {}
        self.breadcrumb_items = {}
        self.setup_blueprint()

        def condition(context):
            return not current_user.is_anonymous and security.has_role(
                current_user, AdminRole
            )

        self.nav_root = NavGroup(
            "admin", "root", title=_l("Admin"), endpoint=None, condition=condition
        )

        for panel in panels:
            self.register_panel(panel)

        app = kwargs.pop("app", None)
        if app is not None:
            self.init_app(app)
コード例 #45
0
ファイル: forms.py プロジェクト: abilian/abilian-sbe
    "img": ["src", "alt", "title"],
}

ALLOWED_STYLES = ["text-align"]

WIDGET_ALLOWED = {}
for attr in ALLOWED_TAGS:
    allowed = ALLOWED_ATTRIBUTES.get(attr, True)
    if not isinstance(allowed, bool):
        allowed = {tag: True for tag in allowed}
    WIDGET_ALLOWED[attr] = allowed

# instantiate this one before PostForm fields, so that it is listed first
# when Threadform is displayed
_TITLE_FIELD = StringField(
    label=_l("Title"), filters=(strip,), validators=[required(), Length(max=150)]
)


class BasePostForm(Form):
    message = TextAreaField(
        label=_l("Message"),
        widget=RichTextWidget(allowed_tags=WIDGET_ALLOWED),
        filters=(strip,),
        validators=[required()],
    )
    attachments = FileField(
        label=_l("Attachments"), multiple=True, validators=[optional()]
    )

    def validate_message(self, field):
コード例 #46
0
ファイル: frontend.py プロジェクト: debon/abilian-core
  def can_create(self):
    create_cls = self.module.create_cls
    permission = create_cls.permission
    cls_permissions = dict(self.Model.__default_permissions__)

    if self.permission in cls_permissions:
      security = current_app.services['security']
      return security.has_permission(current_user,
                                     create_cls.permission,
                                     obj=self.obj,
                                     roles=cls_permissions[permission])
    return False


EDIT_ACTION = Action(
  'module', 'object:view', title=_l(u'Edit'),
  button='default', condition=lambda ctx: ctx['view'].can_edit,
  icon=FAIcon('edit'),
  url=lambda ctx: url_for('.entity_edit',
                          **{ctx['view'].pk: ctx['view'].obj.id}),
)

DELETE_ACTION = Action(
  'module', 'object:view', title=_l(u'Delete'),
  button='danger', condition=lambda ctx: ctx['view'].can_delete,
  icon=FAIcon('trash fa-inverse'),
  url=lambda ctx: url_for('.entity_delete',
                          **{ctx['view'].pk: ctx['view'].obj.id}),
)
DELETE_ACTION.template = 'widgets/frontend_action_delete_confim.html'
コード例 #47
0
ファイル: views.py プロジェクト: abilian/abilian-core
    base_template = "admin/_base.html"

    def index_url(self):
        return url_for(".groups")

    def view_url(self):
        return url_for(".groups_group", group_id=self.obj.id)


# those buttons are made to have valid edit actions, but will not be shown in
# edit forms: they must be availabe only during POST
ADD_USER_BUTTON = ButtonAction(
    "form",
    "add_user",
    condition=lambda v: request.method == "POST",
    title=_l("Add"),
    btn_class="primary",
)

REMOVE_USER_BUTTON = ButtonAction(
    "form",
    "remove_user",
    condition=lambda v: request.method == "POST",
    btn_class="danger",
    icon=FAIcon("times"),
    title="",
)


class GroupView(GroupBase, views.ObjectView):
    template = "admin/group_view.html"
コード例 #48
0
ファイル: models.py プロジェクト: debon/abilian-core
    roles.sort()
    return roles


class RoleType(UniqueNameType):
  """
  Store :class:`Role`

  Usage::
    RoleType()
  """
  Type = Role


#: marker for role assigned to 'Anonymous'
Anonymous = Role('anonymous', _l(u'role_anonymous'), assignable=False)

#: marker for role assigned to 'Authenticated'
Authenticated = Role('authenticated', _l(u'role_authenticated'), assignable=False)

#: marker for `admin` role
Admin = Role('admin', _l(u'role_administrator'))

#: marker for `manager` role
Manager = Role('manager', _l(u'role_manager'), assignable=False)

Creator = Role('creator', assignable=False)
Owner = Role('owner', assignable=False)
Reader = Role('reader', assignable=False)
Writer = Role('writer', assignable=False)
コード例 #49
0
ファイル: actions.py プロジェクト: abilian/abilian-sbe
    def url(self, context=None):
        event = context.get("object")
        return url_for(
            "." + self.name, community_id=g.community.slug, event_id=event.id
        )


def is_admin(context):
    security = get_service("security")
    return security.has_role(current_user, Admin, object=context.get("object"))


_actions = [
    CalendarAction(
        "calendar:global", "new_event", _l("Create a new event"), icon="plus"
    ),
    CalendarAction("calendar:global", "index", _l("Upcoming events"), icon="list"),
    EventAction("calendar:event", "event", _l("View event"), icon=FAIcon("eye")),
    EventAction(
        "calendar:event", "event_edit", _l("Edit event"), icon=FAIcon("pencil")
    ),
]


def register_actions(state):
    if not actions.installed(state.app):
        return
    with state.app.app_context():
        actions.register(*_actions)
コード例 #50
0
ファイル: tasks.py プロジェクト: abilian/abilian-sbe
from abilian.core.util import md5, unwrap
from abilian.i18n import _l, render_template_i18n
from abilian.web import url_for
from celery import shared_task
from celery.schedules import crontab
from celery.utils.log import get_task_logger
from flask import current_app, g
from flask_babel import get_locale
from flask_mail import Message
from itsdangerous import Serializer
from six import text_type

from .forms import ALLOWED_ATTRIBUTES, ALLOWED_STYLES, ALLOWED_TAGS
from .models import Post, PostAttachment, Thread

MAIL_REPLY_MARKER = _l("_____Write above this line to post_____")

# logger = logging.getLogger(__package__)
# Celery logger
logger = get_task_logger(__name__)


def init_app(app):
    global check_maildir
    if app.config["INCOMING_MAIL_USE_MAILDIR"]:
        make_task = periodic_task(run_every=crontab(minute="*"))
        check_maildir = make_task(check_maildir)


@shared_task()
def send_post_by_email(post_id):
コード例 #51
0
ファイル: object.py プロジェクト: debon/abilian-core
  def redirect_to_index(self):
    return redirect(self.index_url())

  @property
  def template_kwargs(self):
    """
    provides :attr:`form` to templates
    """
    kw = super(ObjectView, self).template_kwargs
    kw['form'] = self.form
    return kw


CANCEL_BUTTON = ButtonAction(
  'form', 'cancel', title=_l(u'Cancel'),
  btn_class='default cancel'  # .cancel: if jquery.validate is used it will
)                              # properly skip validation

EDIT_BUTTON = ButtonAction('form', 'edit', btn_class='primary',
                           title=_l(u'Save'))


class ObjectEdit(ObjectView):
  """
  Edit objects
  """
  template = 'default/object_edit.html'
  decorators = (csrf.support_graceful_failure,)
  permission = WRITE
コード例 #52
0
ファイル: views.py プロジェクト: debon/abilian-core
)
from .forms import CommentForm

bp = Blueprint('comments', __name__, url_prefix='/comments')

def _default_comment_view(obj, obj_type, obj_id, **kwargs):
  entity = obj.entity
  return url_for(entity, _anchor='comment-{}'.format(obj.id))


@bp.record_once
def register_default_view(state):
  state.app.default_view.register(Comment, _default_comment_view)

COMMENT_BUTTON = ButtonAction('form', 'edit', btn_class='primary',
                              title=_l(u'Post'))


class BaseCommentView(object):
  Model = Comment
  Form = CommentForm

  #: commented entity
  entity = None

  def init_object(self, args, kwargs):
    args, kwargs = super(BaseCommentView, self).init_object(args, kwargs)
    entity_id = kwargs.pop('entity_id', None)
    if entity_id is not None:
      self.entity = Entity.query.get(entity_id)
コード例 #53
0
ファイル: forms.py プロジェクト: abilian/abilian-sbe
 def validate_end(self, field):
     if self.start.data > self.end.data:
         raise ValidationError(_l("End date/time must be after start"))
コード例 #54
0
ファイル: views.py プロジェクト: debon/abilian-core
  Form = GroupAdminForm
  pk = 'group_id'
  base_template = 'admin/_base.html'

  def index_url(self):
    return url_for('.groups')

  def view_url(self):
    return url_for('.groups_group', group_id=self.obj.id)


# those buttons are made to have valid edit actions, but will not be shown in
# edit forms: they must be availabe only during POST
ADD_USER_BUTTON = ButtonAction('form', 'add_user',
                               condition=lambda v: request.method == 'POST',
                               title=_l(u'Add'), btn_class='primary')

REMOVE_USER_BUTTON = ButtonAction('form', 'remove_user',
                                  condition=lambda v: request.method == 'POST',
                                  btn_class='danger',
                                  icon=FAIcon('times'), title="", )


class GroupView(GroupBase, views.ObjectView):
  template = 'admin/group_view.html'

  def breadcrumb(self):
    label = render_template_string(u'<em>{{ g }}</em>', g=self.obj.name)
    return BreadcrumbItem(label=label, url=u'', description=self.obj.name)

  @property
コード例 #55
0
ファイル: object.py プロジェクト: abilian/abilian-core
    def redirect_to_index(self):
        return redirect(self.index_url())

    @property
    def template_kwargs(self):
        """Provides :attr:`form` to templates."""
        kw = super().template_kwargs
        kw["form"] = self.form
        return kw


CANCEL_BUTTON = ButtonAction(
    "form",
    "cancel",
    title=_l("Cancel"),
    # .cancel: if jquery.validate is used it will properly skip validation
    btn_class="default cancel",
)

EDIT_BUTTON = ButtonAction("form", "edit", btn_class="primary", title=_l("Save"))

ADD_ANOTHER_BUTTON = ButtonAction(
    "form",
    "create_add_another",
    btn_class="primary",
    title=_l("Create and add another"),
    condition=lambda ctx: getattr(ctx["view"], "add_another_button", False),
)

コード例 #56
0
ファイル: views.py プロジェクト: debon/abilian-core
from .forms import AttachmentForm

bp = Blueprint('attachments', __name__, url_prefix='/attachments')


def _default_attachment_view(obj, obj_type, obj_id, **kwargs):
  entity = obj.entity
  return url_for(entity, _anchor='attachment-{}'.format(obj.id))


@bp.record_once
def register_default_view(state):
  state.app.default_view.register(Attachment, _default_attachment_view)

UPLOAD_BUTTON = ButtonAction('form', 'edit', btn_class='primary',
                             title=_l(u'Send'))


class BaseAttachmentView(object):
  """
  Mixin for attachment views
  """
  Model = Attachment
  Form = AttachmentForm

  #: owning entity
  entity = None

  def init_object(self, args, kwargs):
    args, kwargs = super(BaseAttachmentView, self).init_object(args, kwargs)
    entity_id = kwargs.pop('entity_id', None)
コード例 #57
0
ファイル: views.py プロジェクト: abilian/abilian-sbe
        self.linked_group = form.linked_group.data or None
        if self.linked_group:
            self.linked_group = Group.query.get(int(self.linked_group))
        del form.linked_group

    def after_populate_obj(self):
        self.obj.group = self.linked_group


add_url(
    "/<string:community_id>/settings",
    view_func=CommunityEdit.as_view(
        "settings",
        view_endpoint=".community",
        message_success=_l("Community settings saved successfully."),
    ),
)


class CommunityCreate(views.ObjectCreate, CommunityEdit):
    title = _l("Create community")
    decorators = views.ObjectCreate.decorators + (require_admin,)
    template = views.ObjectCreate.template
    base_template = views.ObjectCreate.base_template

    def breadcrumb(self):
        return BreadcrumbItem(label=_("Create new community"))

    def message_success(self):
        return _("Community %(name)s created successfully", name=self.obj.name)
コード例 #58
0
ファイル: models.py プロジェクト: abilian/abilian-core
    @classmethod
    def assignable_roles(cls):
        return sorted(r for r in cls.__instances__.values() if r.assignable)


class RoleType(UniqueNameType):
    """Store :class:`Role`

    Usage:: RoleType()
    """

    Type = Role


#: marker for role assigned to 'Anonymous'
Anonymous = Role("anonymous", _l("role_anonymous"), assignable=False)

#: marker for role assigned to 'Authenticated'
Authenticated = Role("authenticated", _l("role_authenticated"), assignable=False)

#: marker for `admin` role
Admin = Role("admin", _l("role_administrator"))

#: marker for `manager` role
Manager = Role("manager", _l("role_manager"), assignable=False)

Creator = Role("creator", assignable=False)
Owner = Role("owner", assignable=False)
Reader = Role("reader", assignable=False)
Writer = Role("writer", assignable=False)
コード例 #59
0
ファイル: views.py プロジェクト: abilian/abilian-core
from .forms import CommentForm

bp = Blueprint("comments", __name__, url_prefix="/comments")


def _default_comment_view(obj, obj_type, obj_id, **kwargs):
    entity = obj.entity
    return url_for(entity, _anchor=f"comment-{obj.id}")


@bp.record_once
def register_default_view(state):
    state.app.default_view.register(Comment, _default_comment_view)


COMMENT_BUTTON = ButtonAction("form", "edit", btn_class="primary", title=_l("Post"))


class BaseCommentView:
    Model = Comment
    Form = CommentForm

    #: commented entity
    entity = None  # type: Optional[Entity]

    def init_object(self, args, kwargs):
        args, kwargs = super().init_object(args, kwargs)
        entity_id = kwargs.pop("entity_id", None)
        if entity_id is not None:
            self.entity = Entity.query.get(entity_id)
コード例 #60
0
ファイル: service.py プロジェクト: mmariani/abilian-core
"""
from flask import Blueprint, url_for, request, redirect, abort, g
from flask.ext.login import current_user

from abilian.i18n import _, _l
from abilian.core.extensions import db
from abilian.core import signals
from abilian.web.nav import NavItem, BreadcrumbItem, Endpoint
from abilian.services.auth.service import user_menu

from abilian.services.base import Service, ServiceState
from .models import UserPreference

user_menu.items.insert(
  0,
  NavItem('user', 'preferences', title=_l(u'Preferences'), icon='cog',
          url=lambda context: request.url_root + 'preferences',
          condition=lambda context: not current_user.is_anonymous()
          ))


class PreferenceState(ServiceState):
  panels = None
  blueprint = None
  blueprint_registered = False

  def __init__(self, *args, **kwargs):
    ServiceState.__init__(self, *args, **kwargs)
    self.panels = []
    self.breadcrumb_items = {}