def view_on_site(self, request, obj, fieldname, *args, **kwargs): available = obj.is_available endpoint = kwargs.pop( 'endpoint', 'flaskpress.core.detail' if available else 'flaskpress.core.preview') return html.a( href=obj.get_absolute_url(endpoint), target='_blank', )(html.i(class_="icon icon-eye-open", style="margin-right: 5px;")(), _l('View on site') if available else _l('Preview on site'))
class ModelAdmin(ThemeMixin, Roled, ModelView): form_subdocuments = {} datetime_format = "%Y-%m-%d %H:%M" formatters = { 'datetime': format_datetime, 'view_on_site': view_on_site, 'ul': format_ul, 'status': format_status, 'get_url': get_url, 'link': format_link } column_formatters_args = {} def get_datetime_format(self): return current_app.config.get('DATETIME_FORMAT', self.datetime_format) def get_instance(self, i): try: return self.model.objects.get(id=i) except self.model.DoesNotExist: flash(_("Item not found %(i)s", i=i), "error") @action('export_to_json', _l('Export as json')) def export_to_json(self, ids): qs = self.model.objects(id__in=ids) return Response(qs.to_json(), mimetype="text/json", headers={ "Content-Disposition": "attachment;filename=%s.json" % self.model.__name__.lower() }) @action('export_to_csv', _l('Export as csv')) def export_to_csv(self, ids): qs = json.loads(self.model.objects(id__in=ids).to_json()) def generate(): yield ','.join(list(max(qs, key=lambda x: len(x)).keys())) + '\n' for item in qs: yield ','.join([str(i) for i in list(item.values())]) + '\n' return Response(generate(), mimetype="text/csv", headers={ "Content-Disposition": "attachment;filename=%s.csv" % self.model.__name__.lower() })
class PublishActions(object): @action('toggle_publish', _l('Publish/Unpublish'), _l('Publish/Unpublish?')) def action_toggle_publish(self, ids): for i in ids: instance = self.get_instance(i) instance.published = not instance.published instance.save() count = len(ids) flash( _n('Item successfully published/Unpublished.', '%(count)s items were successfully published/Unpublished.', count, count=count))
class ContentActions(object): @action('clone_item', _l('Create a copy'), _l('Are you sure you want a copy?')) def action_clone_item(self, ids): if len(ids) > 1: flash(_("You can select only one item for this action"), 'error') return instance = self.get_instance(ids[0]) new = instance.from_json(instance.to_json()) new.id = None new.published = False new.last_updated_by = User.objects.get(id=current_user.id) new.updated_at = datetime.datetime.now() new.slug = "{0}-{1}".format(new.slug, random.getrandbits(32)) new.save() return redirect(url_for('.edit_view', id=new.id))
def validate_long_slug(self): self._create_mpath_long_slug() filters = dict(long_slug=self.long_slug) if self.id: filters['id__ne'] = self.id exist = self.__class__.objects(**filters) if exist.count(): if current_app.config.get('SMART_SLUG_ENABLED', False): self.slug = "{0}-{1}".format(self.slug, random.getrandbits(32)) self._create_mpath_long_slug() else: raise db.ValidationError( _l("%(slug)s slug already exists", slug=self.long_slug))
class CustomValue(db.EmbeddedDocument): FORMATS = ( ('json', "json"), ('text', "text"), ('int', "int"), ('float', "float"), ) DEFAULT_FORMATTER = default_formatter FORMATTERS = { 'json': json.loads, 'text': DEFAULT_FORMATTER, 'int': int, 'float': float } REVERSE_FORMATTERS = { 'json': lambda val: val if isinstance(val, str) else json.dumps(val), 'text': DEFAULT_FORMATTER, 'int': DEFAULT_FORMATTER, 'float': DEFAULT_FORMATTER } name = db.StringField(max_length=50, required=True) rawvalue = db.StringField(verbose_name=_l("Value"), required=True) formatter = db.StringField(choices=FORMATS, default="text", required=True) @property def value(self): return self.FORMATTERS.get(self.formatter, self.DEFAULT_FORMATTER)(self.rawvalue) @value.setter def value(self, value): self.rawvalue = self.REVERSE_FORMATTERS.get(self.formatter, self.STR_FORMATTER)(value) def clean(self): try: self.value except Exception as e: raise Exception(e.message) super(CustomValue, self).clean() def __unicode__(self): return u"{s.name} -> {s.value}".format(s=self)
def clean(self): homepage = Channel.objects(is_homepage=True) if self.is_homepage and homepage and self not in homepage: raise db.ValidationError(_l("Home page already exists")) super(Channel, self).clean()
class ChannelAdmin(ContentActions, PublishActions, ModelAdmin): roles_accepted = ('admin', 'editor', 'author') column_list = ('title', 'long_slug', 'is_homepage', 'channel_type', 'created_at', 'available_at', 'published', 'view_on_site') column_filters = ['published', 'is_homepage', 'include_in_rss', 'show_in_menu', 'indexable'] column_searchable_list = ('title', 'description') form_columns = ['title', 'slug', 'content_format', 'description', 'parent', 'is_homepage', 'roles', 'include_in_rss', 'indexable', 'show_in_menu', 'order', 'per_page', 'tags', 'sort_by', 'link_in_menu', 'published', 'canonical_url', 'values', 'channel_type', 'inherit_parent', 'content_filters', 'available_at', 'available_until', 'render_content', 'redirect_url'] column_formatters = { 'view_on_site': ModelAdmin.formatters.get('view_on_site'), 'created_at': ModelAdmin.formatters.get('datetime'), 'available_at': ModelAdmin.formatters.get('datetime') } form_subdocuments = {} form_widget_args = { 'title': {'style': 'width: 400px'}, 'slug': {'style': 'width: 400px'}, } form_args = { 'description': {'widget': TextEditor()}, 'slug': {'widget': PrepopulatedText(master='title')} } form_ajax_refs = { 'render_content': AjaxModelLoader('render_content', Content, fields=['title', 'slug']), 'parent': {'fields': ['title', 'slug', 'long_slug']}, } @action( 'set_homepage', _l('Set as homepage'), _l('Set as homepage?') ) def action_set_homepage(self, ids): if len(ids) > 1: flash( _("You can select only one item for this action"), 'error' ) return instance = self.get_instance(ids[0]) if instance.is_homepage: flash( _("Already homepage"), 'error' ) return current_homepage = self.model.objects.filter(is_homepage=True) try: current_homepage.update(is_homepage=False) instance.is_homepage = True instance.save() except Exception as e: current_homepage.update(is_homepage=True) flash(_('Error setting channel as homepage %s', e), 'error') else: flash(_('Channel set as homepage'))
def clean(self): current_names = [value.name for value in self.values] for name in current_names: if current_names.count(name) > 1: raise Exception(_l("%(name)s already exists", name=name)) super(HasCustomValue, self).clean()