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