Initial porting of ScribeEngine to Flask
This commit is contained in:
commit
45ee572660
28
README.rst
Normal file
28
README.rst
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
ScribeEngine
|
||||||
|
============
|
||||||
|
|
||||||
|
ScribeEngine is an open source blog engine written in Python and Flask.
|
||||||
|
|
||||||
|
Installation and Setup
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
Install ScribeEngine using ``pip``::
|
||||||
|
|
||||||
|
pip install ScribeEngine
|
||||||
|
|
||||||
|
Create a config file with these options set::
|
||||||
|
|
||||||
|
[mail]
|
||||||
|
server = mail.example.com
|
||||||
|
port = 25
|
||||||
|
use_tls = false
|
||||||
|
username = me
|
||||||
|
password = secret
|
||||||
|
|
||||||
|
[sqlalchemy]
|
||||||
|
database_uri = sqlite:///scribeengine.sqlite
|
||||||
|
|
||||||
|
Run a local server::
|
||||||
|
|
||||||
|
$ python -m scribeengine.application.run()
|
||||||
|
|
15
config.ini.default
Normal file
15
config.ini.default
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
[sqlalchemy]
|
||||||
|
|
||||||
|
|
||||||
|
[mail]
|
||||||
|
username = email@example.com
|
||||||
|
password = password
|
||||||
|
default_sender = sender <noreply@example.com>
|
||||||
|
server = smtp.gmail.com
|
||||||
|
port = 465
|
||||||
|
use_ssl = true
|
||||||
|
use_tls = false
|
||||||
|
|
||||||
|
[theme]
|
||||||
|
paths =
|
||||||
|
default =
|
3
devserver.py
Normal file
3
devserver.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
from scribeengine import application
|
||||||
|
application.run(host='0.0.0.0', port=8080, debug=True)
|
12
requirements.txt
Normal file
12
requirements.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
Flask
|
||||||
|
Flask-Admin
|
||||||
|
Flask-Login
|
||||||
|
Flask-Mail
|
||||||
|
Flask-SQLAlchemy
|
||||||
|
Flask-Themes
|
||||||
|
Flask-Uploads
|
||||||
|
Flask-User
|
||||||
|
Flask-WTF
|
||||||
|
passlib
|
||||||
|
py-bcrypt
|
||||||
|
pycrypto
|
61
scribeengine/__init__.py
Normal file
61
scribeengine/__init__.py
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# ScribeEngine - Open Source Blog Software #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# Copyright (c) 2010-2017 Raoul Snyman #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# This program is free software; you can redistribute it and/or modify it #
|
||||||
|
# under the terms of the GNU General Public License as published by the Free #
|
||||||
|
# Software Foundation; version 2 of the License. #
|
||||||
|
# #
|
||||||
|
# This program is distributed in the hope that it will be useful, but WITHOUT #
|
||||||
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
||||||
|
# more details. #
|
||||||
|
# #
|
||||||
|
# You should have received a copy of the GNU General Public License along #
|
||||||
|
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||||
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
|
###############################################################################
|
||||||
|
"""
|
||||||
|
The :mod:`~scribeengine` module sets up and runs ScribeEngine
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
|
||||||
|
from flask import Flask
|
||||||
|
from flask_mail import Mail
|
||||||
|
from flask_themes import setup_themes
|
||||||
|
from flask_user import SQLAlchemyAdapter, UserManager
|
||||||
|
|
||||||
|
from scribeengine.config import read_config_from_file
|
||||||
|
from scribeengine.db import db
|
||||||
|
from scribeengine.models import User
|
||||||
|
|
||||||
|
|
||||||
|
def create_app(config_file=None):
|
||||||
|
"""
|
||||||
|
Create the application object
|
||||||
|
"""
|
||||||
|
application = Flask('ScribeEngine')
|
||||||
|
# Set up configuration
|
||||||
|
if not config_file:
|
||||||
|
if os.environ.get('SCRIBEENGINE_CONFIG'):
|
||||||
|
config_file = os.environ['SCRIBEENGINE_CONFIG']
|
||||||
|
elif os.path.exists('sundaybuilder.conf'):
|
||||||
|
config_file = 'sundaybuilder.conf'
|
||||||
|
if config_file:
|
||||||
|
application.config.update(read_config_from_file(config_file))
|
||||||
|
# Set up mail, themes
|
||||||
|
Mail(application)
|
||||||
|
setup_themes(application, app_identifier='ScribeEngine')
|
||||||
|
# Set up database
|
||||||
|
db.init_app(application)
|
||||||
|
db.create_all()
|
||||||
|
# Setup Flask-User
|
||||||
|
db_adapter = SQLAlchemyAdapter(db, User) # Register the User model
|
||||||
|
user_manager = UserManager(db_adapter, application) # Initialize Flask-User
|
||||||
|
# Register all the blueprints
|
||||||
|
# Return the application object
|
||||||
|
return application
|
69
scribeengine/config.py
Normal file
69
scribeengine/config.py
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# ScribeEngine - Open Source Blog Software #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# Copyright (c) 2010-2017 Raoul Snyman #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# This program is free software; you can redistribute it and/or modify it #
|
||||||
|
# under the terms of the GNU General Public License as published by the Free #
|
||||||
|
# Software Foundation; version 2 of the License. #
|
||||||
|
# #
|
||||||
|
# This program is distributed in the hope that it will be useful, but WITHOUT #
|
||||||
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
||||||
|
# more details. #
|
||||||
|
# #
|
||||||
|
# You should have received a copy of the GNU General Public License along #
|
||||||
|
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||||
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
|
###############################################################################
|
||||||
|
"""
|
||||||
|
The :mod:`~scribeengine.config` module contains helper classes for config handling
|
||||||
|
"""
|
||||||
|
from configparser import ConfigParser
|
||||||
|
|
||||||
|
BOOLEAN_VALUES = ['yes', 'true', 'on', 'no', 'false', 'off']
|
||||||
|
|
||||||
|
|
||||||
|
def _fix_special_cases(config):
|
||||||
|
"""
|
||||||
|
Deal with special cases
|
||||||
|
"""
|
||||||
|
if 'THEME_PATHS' in config:
|
||||||
|
config['THEME_PATHS'] = [p.strip() for p in config['THEME_PATHS'].split(',') if p.strip()]
|
||||||
|
|
||||||
|
|
||||||
|
def read_config_from_file(filename):
|
||||||
|
"""
|
||||||
|
Read the Flask configuration from a config file
|
||||||
|
"""
|
||||||
|
flask_config = {}
|
||||||
|
config = ConfigParser()
|
||||||
|
config.read(filename)
|
||||||
|
for section in config.sections():
|
||||||
|
for option in config.options(section):
|
||||||
|
# Get the value, skip it if it is blank
|
||||||
|
string_value = config.get(section, option)
|
||||||
|
if not string_value:
|
||||||
|
continue
|
||||||
|
# Try to figure out what type it is
|
||||||
|
if string_value.isnumeric() and '.' in string_value:
|
||||||
|
value = config.getfloat(section, option)
|
||||||
|
elif string_value.isnumeric():
|
||||||
|
value = config.getint(section, option)
|
||||||
|
elif string_value.lower() in BOOLEAN_VALUES:
|
||||||
|
value = config.getboolean(section, option)
|
||||||
|
else:
|
||||||
|
value = string_value
|
||||||
|
# Set up the configuration key
|
||||||
|
if section == 'flask':
|
||||||
|
# Options in the flask section don't need FLASK_*
|
||||||
|
key = option.upper()
|
||||||
|
else:
|
||||||
|
key = '{}_{}'.format(section, option).upper()
|
||||||
|
# Save this into our flask config dictionary
|
||||||
|
flask_config[key] = value
|
||||||
|
_fix_special_cases(flask_config)
|
||||||
|
return flask_config
|
41
scribeengine/db.py
Normal file
41
scribeengine/db.py
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# ScribeEngine - Open Source Blog Software #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# Copyright (c) 2010-2017 Raoul Snyman #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# This program is free software; you can redistribute it and/or modify it #
|
||||||
|
# under the terms of the GNU General Public License as published by the Free #
|
||||||
|
# Software Foundation; version 2 of the License. #
|
||||||
|
# #
|
||||||
|
# This program is distributed in the hope that it will be useful, but WITHOUT #
|
||||||
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
||||||
|
# more details. #
|
||||||
|
# #
|
||||||
|
# You should have received a copy of the GNU General Public License along #
|
||||||
|
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||||
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
|
###############################################################################
|
||||||
|
"""
|
||||||
|
The :mod:`~scribeengine.db` module sets up SQLAlchemy
|
||||||
|
"""
|
||||||
|
from flask_sqlalchemy import SQLAlchemy
|
||||||
|
|
||||||
|
# Get the db object
|
||||||
|
db = SQLAlchemy()
|
||||||
|
|
||||||
|
# Extract the classes to make them prettier
|
||||||
|
Model = db.Model
|
||||||
|
Table = db.Table
|
||||||
|
Column = db.Column
|
||||||
|
ForeignKey = db.ForeignKey
|
||||||
|
String = db.String
|
||||||
|
Text = db.Text
|
||||||
|
Integer = db.Integer
|
||||||
|
Boolean = db.Boolean
|
||||||
|
DateTime = db.DateTime
|
||||||
|
relationship = db.relationship
|
||||||
|
backref = db.backref
|
241
scribeengine/models.py
Normal file
241
scribeengine/models.py
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# ScribeEngine - Open Source Blog Software #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# Copyright (c) 2010-2017 Raoul Snyman #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# This program is free software; you can redistribute it and/or modify it #
|
||||||
|
# under the terms of the GNU General Public License as published by the Free #
|
||||||
|
# Software Foundation; version 2 of the License. #
|
||||||
|
# #
|
||||||
|
# This program is distributed in the hope that it will be useful, but WITHOUT #
|
||||||
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
||||||
|
# more details. #
|
||||||
|
# #
|
||||||
|
# You should have received a copy of the GNU General Public License along #
|
||||||
|
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||||
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
|
###############################################################################
|
||||||
|
"""
|
||||||
|
The :mod:`~scribeengine.models` module contains all the database models
|
||||||
|
"""
|
||||||
|
from flask_user import UserMixin
|
||||||
|
from sqlalchemy import func
|
||||||
|
|
||||||
|
from scribeengine.db import Model, Table, Column, ForeignKey, String, Text, Integer, Boolean, DateTime, \
|
||||||
|
relationship, backref
|
||||||
|
|
||||||
|
|
||||||
|
categories_posts = Table(
|
||||||
|
'categories_posts',
|
||||||
|
Column('category_id', Integer, ForeignKey('categories.id'), primary_key=True),
|
||||||
|
Column('post_id', Integer, ForeignKey('posts.id'), primary_key=True)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
permissions_roles = Table(
|
||||||
|
'permissions_roles',
|
||||||
|
Column('permission_id', Integer, ForeignKey('permissions.id'), primary_key=True),
|
||||||
|
Column('role_id', Integer, ForeignKey('roles.id'), primary_key=True)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
posts_tags = Table(
|
||||||
|
'posts_tags',
|
||||||
|
Column('post_id', Integer, ForeignKey('posts.id'), primary_key=True),
|
||||||
|
Column('tag_id', Integer, ForeignKey('tags.id'), primary_key=True)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
roles_users = Table(
|
||||||
|
'roles_users',
|
||||||
|
Column('user_id', Integer, ForeignKey('users.id'), primary_key=True),
|
||||||
|
Column('role_id', Integer, ForeignKey('roles.id'), primary_key=True)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class Category(Model):
|
||||||
|
"""
|
||||||
|
This is a category for blog posts.
|
||||||
|
"""
|
||||||
|
__tablename__ = 'categories'
|
||||||
|
|
||||||
|
id = Column(Integer, primary_key=True)
|
||||||
|
name = Column(String(100), nullable=False)
|
||||||
|
description = Column(Text)
|
||||||
|
url = Column(String(255), nullable=False, index=True, unique=True)
|
||||||
|
|
||||||
|
|
||||||
|
class Comment(Model):
|
||||||
|
"""
|
||||||
|
All blog posts have comments. This is a single comment.
|
||||||
|
"""
|
||||||
|
__tablename__ = 'comments'
|
||||||
|
|
||||||
|
id = Column(Integer, primary_key=True)
|
||||||
|
post_id = Column(Integer, ForeignKey('posts.id'), nullable=True)
|
||||||
|
user_id = Column(Integer, ForeignKey('users.id'), nullable=False)
|
||||||
|
title = Column(String(100), nullable=False)
|
||||||
|
body = Column(Text, nullable=False)
|
||||||
|
status = Column(String(10), default='moderated')
|
||||||
|
created = Column(DateTime, server_default=func.now())
|
||||||
|
modified = Column(DateTime, server_default=func.now())
|
||||||
|
|
||||||
|
|
||||||
|
class File(Model):
|
||||||
|
"""
|
||||||
|
A file in the media library.
|
||||||
|
"""
|
||||||
|
__tablename__ = 'files'
|
||||||
|
|
||||||
|
id = Column(Integer, primary_key=True)
|
||||||
|
user_id = Column(Integer, ForeignKey('users.id'), nullable=False)
|
||||||
|
media_type_id = Column(Integer, ForeignKey('media_types.id'), nullable=False)
|
||||||
|
filename = Column(String(255), nullable=False, index=True)
|
||||||
|
mimetype = Column(String(255))
|
||||||
|
path = Column(String(255))
|
||||||
|
size = Column(Integer, default=0)
|
||||||
|
|
||||||
|
|
||||||
|
class MediaType(Model):
|
||||||
|
"""
|
||||||
|
Distinguishes between different types of media.
|
||||||
|
"""
|
||||||
|
__tablename__ = 'media_types'
|
||||||
|
|
||||||
|
id = Column(Integer, primary_key=True)
|
||||||
|
title = Column(String(255), nullable=False, index=True)
|
||||||
|
|
||||||
|
files = relationship('File', backref='media_type')
|
||||||
|
|
||||||
|
|
||||||
|
class Page(Model):
|
||||||
|
"""
|
||||||
|
A page on the blog. This is separate from a blog entry, for things like
|
||||||
|
about pages.
|
||||||
|
"""
|
||||||
|
__tablename__ = 'pages'
|
||||||
|
|
||||||
|
id = Column(Integer, primary_key=True)
|
||||||
|
title = Column(String(255), nullable=False)
|
||||||
|
body = Column(Text)
|
||||||
|
url = Column(String(255), nullable=False, index=True, unique=True)
|
||||||
|
created = Column(DateTime, server_default=func.now())
|
||||||
|
modified = Column(DateTime, server_default=func.now())
|
||||||
|
|
||||||
|
|
||||||
|
class Permission(Model):
|
||||||
|
"""
|
||||||
|
A single permission.
|
||||||
|
"""
|
||||||
|
__tablename__ = 'permissions'
|
||||||
|
|
||||||
|
id = Column(Integer, primary_key=True)
|
||||||
|
name = Column(String(80), nullable=False, index=True)
|
||||||
|
description = Column(Text)
|
||||||
|
|
||||||
|
|
||||||
|
class Post(Model):
|
||||||
|
"""
|
||||||
|
The most import part of all of this, the blog post.
|
||||||
|
"""
|
||||||
|
__tablename__ = 'posts'
|
||||||
|
|
||||||
|
id = Column(Integer, primary_key=True)
|
||||||
|
user_id = Column(Integer, ForeignKey('users.id'), nullable=False)
|
||||||
|
title = Column(String(255), nullable=False, index=True)
|
||||||
|
body = Column(Text, nullable=False, index=True)
|
||||||
|
url = Column(String(255), nullable=False, index=True)
|
||||||
|
status = Column(String(10), default='draft', index=True)
|
||||||
|
comment_status = Column(String(10), default='open')
|
||||||
|
created = Column(DateTime, server_default=func.now())
|
||||||
|
modified = Column(DateTime, server_default=func.now())
|
||||||
|
|
||||||
|
categories = relationship('Category', backref='posts', secondary=categories_posts)
|
||||||
|
comments = relationship('Comment', backref='post', order_by='Comment.created.asc()')
|
||||||
|
tags = relationship('Tag', backref=backref('posts', order_by='Post.created.desc()'), secondary=posts_tags)
|
||||||
|
|
||||||
|
|
||||||
|
class Role(Model):
|
||||||
|
"""
|
||||||
|
A role defines a set of permissions.
|
||||||
|
"""
|
||||||
|
__tablename__ = 'roles'
|
||||||
|
|
||||||
|
id = Column(Integer, primary_key=True)
|
||||||
|
name = Column(String(80), nullable=False, index=True)
|
||||||
|
description = Column(Text)
|
||||||
|
|
||||||
|
permissions = relationship('Permission', backref='roles', secondary=permissions_roles)
|
||||||
|
|
||||||
|
|
||||||
|
class Tag(Model):
|
||||||
|
"""
|
||||||
|
A tag, an unstructured category, for blog posts.
|
||||||
|
"""
|
||||||
|
__tablename__ = 'tags'
|
||||||
|
|
||||||
|
id = Column(Integer, primary_key=True)
|
||||||
|
name = Column(String(100), nullable=False)
|
||||||
|
url = Column(String(255), nullable=False, index=True)
|
||||||
|
|
||||||
|
|
||||||
|
class User(Model, UserMixin):
|
||||||
|
"""
|
||||||
|
The user.
|
||||||
|
"""
|
||||||
|
__tablename__ = 'users'
|
||||||
|
|
||||||
|
id = Column(Integer, primary_key=True)
|
||||||
|
email = Column(String(200), nullable=False, unique=True, index=True)
|
||||||
|
username = Column(String(200), nullable=False, unique=True, index=True)
|
||||||
|
password = Column(String(64), nullable=False)
|
||||||
|
nick = Column(String(50), nullable=False, index=True)
|
||||||
|
first_name = Column(String(100), default='')
|
||||||
|
last_name = Column(String(100), default='')
|
||||||
|
homepage = Column(String(200), default='')
|
||||||
|
timezone = Column(String(200), default='UTC')
|
||||||
|
activation_key = Column(String(40), default=None)
|
||||||
|
confirmed_at = Column(DateTime)
|
||||||
|
active = Column('is_active', Boolean, nullable=False, server_default='0')
|
||||||
|
|
||||||
|
comments = relationship('Comment', backref='user'),
|
||||||
|
files = relationship('File', backref='user'),
|
||||||
|
posts = relationship('Post', backref='user'),
|
||||||
|
roles = relationship('Role', backref='users', secondary=roles_users)
|
||||||
|
|
||||||
|
def has_permission(self, permission):
|
||||||
|
if isinstance(permission, str):
|
||||||
|
for role in self.roles:
|
||||||
|
for perm in role.permissions:
|
||||||
|
if perm.name == permission:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
elif isinstance(permission, Permission):
|
||||||
|
for role in self.roles:
|
||||||
|
for perm in role.permissions:
|
||||||
|
if perm == permission:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
elif isinstance(permission, list):
|
||||||
|
for role in self.roles:
|
||||||
|
for perm in role.permissions:
|
||||||
|
if perm.name in permission:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class Variable(Model):
|
||||||
|
"""
|
||||||
|
System variables.
|
||||||
|
"""
|
||||||
|
__tablename__ = 'variables'
|
||||||
|
|
||||||
|
key = Column(String(100), primary_key=True, index=True)
|
||||||
|
value = Column(String(100), nullable=False)
|
||||||
|
type = Column(String(10), default='string')
|
41
scribeengine/themes.py
Normal file
41
scribeengine/themes.py
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# ScribeEngine - Open Source Blog Software #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# Copyright (c) 2010-2017 Raoul Snyman #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# This program is free software; you can redistribute it and/or modify it #
|
||||||
|
# under the terms of the GNU General Public License as published by the Free #
|
||||||
|
# Software Foundation; version 2 of the License. #
|
||||||
|
# #
|
||||||
|
# This program is distributed in the hope that it will be useful, but WITHOUT #
|
||||||
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
||||||
|
# more details. #
|
||||||
|
# #
|
||||||
|
# You should have received a copy of the GNU General Public License along #
|
||||||
|
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||||
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
|
###############################################################################
|
||||||
|
"""
|
||||||
|
The :mod:`~scribeengine.themes` module contains some theme helper methods
|
||||||
|
"""
|
||||||
|
from flask import current_app
|
||||||
|
from flask_themes import get_theme, render_theme_template
|
||||||
|
|
||||||
|
|
||||||
|
def get_current_theme():
|
||||||
|
"""
|
||||||
|
Determine the current theme.
|
||||||
|
"""
|
||||||
|
ident = current_app.config.get('THEME_DEFAULT', 'quill')
|
||||||
|
return get_theme(ident)
|
||||||
|
|
||||||
|
|
||||||
|
def render(template, **context):
|
||||||
|
"""
|
||||||
|
Render a template, after selecting a theme
|
||||||
|
"""
|
||||||
|
return render_theme_template(get_current_theme(), template, **context)
|
24
scribeengine/views/__init__.py
Normal file
24
scribeengine/views/__init__.py
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# ScribeEngine - Open Source Blog Software #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# Copyright (c) 2010-2017 Raoul Snyman #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# This program is free software; you can redistribute it and/or modify it #
|
||||||
|
# under the terms of the GNU General Public License as published by the Free #
|
||||||
|
# Software Foundation; version 2 of the License. #
|
||||||
|
# #
|
||||||
|
# This program is distributed in the hope that it will be useful, but WITHOUT #
|
||||||
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
||||||
|
# more details. #
|
||||||
|
# #
|
||||||
|
# You should have received a copy of the GNU General Public License along #
|
||||||
|
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||||
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
|
###############################################################################
|
||||||
|
"""
|
||||||
|
The :mod:`~scribeengine.views` module contains the views for ScribeEngine
|
||||||
|
"""
|
35
scribeengine/views/account.py
Normal file
35
scribeengine/views/account.py
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# ScribeEngine - Open Source Blog Software #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# Copyright (c) 2010-2017 Raoul Snyman #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# This program is free software; you can redistribute it and/or modify it #
|
||||||
|
# under the terms of the GNU General Public License as published by the Free #
|
||||||
|
# Software Foundation; version 2 of the License. #
|
||||||
|
# #
|
||||||
|
# This program is distributed in the hope that it will be useful, but WITHOUT #
|
||||||
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
||||||
|
# more details. #
|
||||||
|
# #
|
||||||
|
# You should have received a copy of the GNU General Public License along #
|
||||||
|
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||||
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
|
###############################################################################
|
||||||
|
"""
|
||||||
|
The :mod:`~scribeengine.views.account` module contains the account views
|
||||||
|
"""
|
||||||
|
from flask import Blueprint
|
||||||
|
from pytz import all_timezones
|
||||||
|
|
||||||
|
from scribeengine.themes import render
|
||||||
|
|
||||||
|
account = Blueprint('account', __file__, prefix='/account')
|
||||||
|
|
||||||
|
|
||||||
|
@account.route('', methods=['GET'])
|
||||||
|
def index(self):
|
||||||
|
return render('/account/index.html', page_title='My Account', timezones=all_timezones)
|
39
setup.py
Normal file
39
setup.py
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
"""
|
||||||
|
The ScribeEngine package
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
from codecs import open
|
||||||
|
from setuptools import setup, find_packages
|
||||||
|
|
||||||
|
HERE = os.path.abspath(os.path.dirname(__file__))
|
||||||
|
|
||||||
|
with open(os.path.join(HERE, 'README.rst'), encoding='utf8') as f:
|
||||||
|
LONG_DESCRIPTION = f.read()
|
||||||
|
with open(os.path.join(HERE, 'requirements.txt'), encoding='utf8') as f:
|
||||||
|
INSTALL_REQUIRES = [line for line in f]
|
||||||
|
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name='ScribeEngine',
|
||||||
|
version='0.2',
|
||||||
|
description='A blog engine written in Python',
|
||||||
|
long_description=LONG_DESCRIPTION,
|
||||||
|
url='https://launchpad.net/scribeengine',
|
||||||
|
author='Raoul Snyman',
|
||||||
|
author_email='raoul@snyman.info',
|
||||||
|
license='GPLv3+',
|
||||||
|
classifiers=[
|
||||||
|
'Development Status :: 4 - Beta',
|
||||||
|
'Environment :: Web Environment,'
|
||||||
|
'Framework :: Flask',
|
||||||
|
'Intended Audience :: End Users/Desktop',
|
||||||
|
'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)',
|
||||||
|
'Operating System :: OS Independent',
|
||||||
|
'Programming Language :: Python :: 3',
|
||||||
|
'Topic :: Internet :: WWW/HTTP :: Dynamic Content :: Content Management System',
|
||||||
|
'Topic :: Internet :: WWW/HTTP :: WSGI :: Application'
|
||||||
|
],
|
||||||
|
keywords='website blog',
|
||||||
|
packages=find_packages(),
|
||||||
|
install_requires=INSTALL_REQUIRES
|
||||||
|
)
|
Reference in New Issue
Block a user