def get_widgets(self, position=None, include_draft=False): """ Get widgets for given position from filesystem. :param position: position or position list :param include_draft: return draft widgets or not :return: an iterable of Widget objects """ def widgets_generator(path): """Loads valid widgets one by one in the given path.""" if os.path.isdir(path): for file in os.listdir(path): _, ext = os.path.splitext(file) format_name = get_standard_format_name(ext[1:]) if format_name is not None: # the format is supported, so load it widget = Widget() widget.format = format_name widget.meta, widget.raw_content = \ FileStorage.read_file(os.path.join(path, file)) yield widget widgets_path = os.path.join(current_app.instance_path, 'widgets') positions = to_list(position) if position is not None else position result = filter( lambda w: (w.position in positions if positions is not None else True) and (include_draft or not w.is_draft), widgets_generator(widgets_path)) return sorted(result, key=lambda w: (w.position, w.order))
def decorator(cls): format_name_lower = format_name.lower() if ext_names is None: _ext_format_mapping[format_name_lower] = format_name_lower else: for ext in to_list(ext_names): _ext_format_mapping[ext.lower()] = format_name_lower _format_parser_mapping[format_name_lower] = cls() return cls
def wrapper(*args, **kwargs): template_ = template if template_ is None: template_ = request.endpoint.split('.', 1)[1].replace( '.', '/') + '.html' context = func(*args, **kwargs) if context is None: context = {} elif not isinstance(context, dict): return context return custom_render_template( list(chain(to_list(template_), templates)), **context)
def custom_render_template(template_name_or_list, **context): """ Try to render templates in the custom folder first, if no custom templates, try the theme's default ones. """ response_str = render_template( functools.reduce(lambda x, y: x + [os.path.join('custom', y), y], to_list(template_name_or_list), []), **context) if hasattr(g, 'status_code'): status_code = g.status_code else: status_code = 200 return response_str, status_code
def get_posts_with_limits(self, include_draft=False, **limits): """ Get all posts and filter them as needed. :param include_draft: return draft posts or not :param limits: other limits to the attrs of the result, should be a dict with string or list values :return: an iterable of Post objects """ filter_funcs = [] for attr in ('title', 'layout', 'author', 'email', 'tags', 'categories'): if limits.get(attr): filter_set = set(to_list(limits.get(attr))) def get_filter_func(filter_set_, attr_): return lambda p: filter_set_.intersection( to_list(getattr(p, attr_))) filter_funcs.append(get_filter_func(filter_set, attr)) for attr in ('created', 'updated'): interval = limits.get(attr) if isinstance(interval, (list, tuple)) and len(interval) == 2 \ and isinstance(interval[0], date) and isinstance( interval[1], date): # [start date(time), end date(time)] start, end = interval start = to_datetime(start) if not isinstance(end, datetime): # 'end' is a date, # we should convert it to 00:00:00 of the next day, # so that posts of that day will be included end = datetime.strptime( '%04d-%02d-%02d' % (end.year, end.month, end.day), '%Y-%m-%d') end += timedelta(days=1) def get_filter_func(attr_, start_dt, end_dt): return lambda p: start_dt <= getattr(p, attr_) < end_dt filter_funcs.append(get_filter_func(attr, start, end)) return self.get_posts(include_draft=include_draft, filter_functions=filter_funcs)
def get_filter_func(filter_set_, attr_): return lambda p: filter_set_.intersection( to_list(getattr(p, attr_)))
def categories(self): return to_list(getattr(self, 'meta', {}).get('categories', []))
def tags(self): return to_list(getattr(self, 'meta', {}).get('tags', []))