# Path: flask_blogging/processor.py
# class PostProcessor(object):
# 
#     _markdown_extensions = [MathJaxExtension(), MetaExtension()]
# 
#     @staticmethod
#     def create_slug(title):
#         return slugify(title)
# 
#     @staticmethod
#     def extract_images(post):
#         regex = re.compile(r'<\s*img [^>]*src="([^"]+)')
#         return regex.findall(post["rendered_text"])
# 
#     @classmethod
#     def construct_url(cls, post):
#         url = url_for("blogging.page_by_id", post_id=post["post_id"],
#                       slug=cls.create_slug(post["title"]))
#         return url
# 
#     @classmethod
#     def render_text(cls, post):
#         md = markdown.Markdown(extensions=cls.all_extensions())
#         post["rendered_text"] = md.convert(post["text"])
#         post["meta"] = md.Meta
# 
#     @classmethod
#     def is_author(cls, post, user):
#         return user.get_id() == u''+str(post['user_id'])
# 
#     @classmethod
#     def process(cls, post, render=True):
#         """
#         This method takes the post data and renders it
#         :param post:
#         :param render:
#         :return:
#         """
#         post["slug"] = cls.create_slug(post["title"])
#         post["editable"] = cls.is_author(post, current_user)
#         post["url"] = cls.construct_url(post)
#         post["priority"] = 0.8
#         if render:
#             cls.render_text(post)
#             post["meta"]["images"] = cls.extract_images(post)
# 
#     @classmethod
#     def all_extensions(cls):
#         return cls._markdown_extensions
# 
#     @classmethod
#     def set_custom_extensions(cls, extensions):
#         if type(extensions) == list:
#             cls._markdown_extensions.extend(extensions)
# 
# Path: flask_blogging/signals.py



    from builtins import object
from .processor import PostProcessor
from flask_principal import Principal, Permission, RoleNeed
from .signals import engine_initialised, post_processed, blueprint_created
from flask_fileupload import FlaskFileUpload
        from .views import create_blueprint
    """

    def __init__(self, app=None, storage=None, post_processor=None,
                 extensions=None, cache=None, file_upload=None):
        """

        :param app: Optional app to use
        :type app: object
        :param storage: The blog storage instance that implements the
         ``Storage`` class interface.
        :type storage: object
        :param post_processor: (optional) The post processor object. If none
         provided, the default post processor is used.
        :type post_processor: object
        :param extensions: (optional) A list of markdown extensions to add to
         post processing step.
        :type extensions: list
        :param cache: (Optional) A Flask-Cache object to enable caching
        :type cache: Object
        :param file_upload: (Optional) A FileUpload object from
         flask_fileupload extension
        :type file_upload: Object
        :return:
        """
        self.app = None
        self.storage = storage
        self.config = None
        self.ffu = None
        self.cache = cache
        self._blogger_permission = None

# Path: flask_blogging/processor.py
# class PostProcessor(object):
# 
#     _markdown_extensions = [MathJaxExtension(), MetaExtension()]
# 
#     @staticmethod
#     def create_slug(title):
#         return slugify(title)
# 
#     @staticmethod
#     def extract_images(post):
#         regex = re.compile(r'<\s*img [^>]*src="([^"]+)')
#         return regex.findall(post["rendered_text"])
# 
#     @classmethod
#     def construct_url(cls, post):
#         url = url_for("blogging.page_by_id", post_id=post["post_id"],
#                       slug=cls.create_slug(post["title"]))
#         return url
# 
#     @classmethod
#     def render_text(cls, post):
#         md = markdown.Markdown(extensions=cls.all_extensions())
#         post["rendered_text"] = md.convert(post["text"])
#         post["meta"] = md.Meta
# 
#     @classmethod
#     def is_author(cls, post, user):
#         return user.get_id() == u''+str(post['user_id'])
# 
#     @classmethod
#     def process(cls, post, render=True):
#         """
#         This method takes the post data and renders it
#         :param post:
#         :param render:
#         :return:
#         """
#         post["slug"] = cls.create_slug(post["title"])
#         post["editable"] = cls.is_author(post, current_user)
#         post["url"] = cls.construct_url(post)
#         post["priority"] = 0.8
#         if render:
#             cls.render_text(post)
#             post["meta"]["images"] = cls.extract_images(post)
# 
#     @classmethod
#     def all_extensions(cls):
#         return cls._markdown_extensions
# 
#     @classmethod
#     def set_custom_extensions(cls, extensions):
#         if type(extensions) == list:
#             cls._markdown_extensions.extend(extensions)
# 
# Path: flask_blogging/signals.py



# Path: flask_blogging/engine.py
    from builtins import object
from .processor import PostProcessor
from flask_principal import Principal, Permission, RoleNeed
from .signals import engine_initialised, post_processed, blueprint_created
from flask_fileupload import FlaskFileUpload
        from .views import create_blueprint

    """

    def __init__(self, app=None, storage=None, post_processor=None,
                 extensions=None, cache=None, file_upload=None):
        """

        :param app: Optional app to use
        :type app: object
        :param storage: The blog storage instance that implements the
         ``Storage`` class interface.
        :type storage: object
        :param post_processor: (optional) The post processor object. If none
         provided, the default post processor is used.
        :type post_processor: object
        :param extensions: (optional) A list of markdown extensions to add to
         post processing step.
        :type extensions: list
        :param cache: (Optional) A Flask-Cache object to enable caching
        :type cache: Object
        :param file_upload: (Optional) A FileUpload object from
         flask_fileupload extension
        :type file_upload: Object
        :return:
        """
        self.app = None
        self.storage = storage
        self.config = None
        self.ffu = None
        self.cache = cache
        self._blogger_permission = None

        self.post_processor = PostProcessor() if post_processor is None \