-
Notifications
You must be signed in to change notification settings - Fork 168
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
beibq
committed
Jan 30, 2018
0 parents
commit 7bc35df
Showing
329 changed files
with
81,016 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# beibq | ||
|
||
beibq是基于flask开发的开源书籍博客。 | ||
|
||
beibq的特点: | ||
|
||
- 极简界面,直观、简单、易用 | ||
- 高效、便捷的在线书籍编辑器,支持Markdown标记语言 | ||
- 响应式设计,自适应各种平台界面 | ||
|
||
beibq的编辑器是使用[bookeditor](https://github.com/chaijunit/bookeditor),这是一个开源的Markdown在线写书编辑器 | ||
|
||
## 安装使用 | ||
|
||
#### 1. 安装依赖包 | ||
|
||
``` | ||
pip install -r requirements.txt | ||
``` | ||
|
||
#### 2. 启动程序 | ||
|
||
``` | ||
python manage.py runserver -h 0.0.0.0 | ||
``` | ||
|
||
#### 3. 配置站点 | ||
在浏览器中输入http://127.0.0.1:5000 | ||
|
||
第一次访问会跳转到配置界面,根据指示配置站点信息后就能使用beibq | ||
|
||
## 建议反馈 | ||
如果您有任何建议和问题,可以通过邮箱方式和我联系 | ||
|
||
- 邮箱: [email protected] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
#coding:utf-8 | ||
from flask import Flask, redirect, url_for, request | ||
from datetime import datetime | ||
from flask_bootstrap import Bootstrap | ||
from app.config_default import Config as DefaultConfig | ||
|
||
|
||
bootstrap = Bootstrap() | ||
|
||
def check_start(app, db): | ||
from app.includes.start import _exist_config, exist_table, load_site, create_path | ||
create_path(app) | ||
app.start = False | ||
if _exist_config(app): | ||
from app.config import Config | ||
app.config.from_object(Config) | ||
if exist_table(app): | ||
load_site(app) | ||
app.start = True | ||
return | ||
@app.before_request | ||
def request_check_start(): | ||
if app.start: | ||
return | ||
ends = frozenset(["admin.setup", "admin.install", "static"]) | ||
if request.endpoint in ends: | ||
return | ||
if not _exist_config(app): | ||
return redirect(url_for("admin.setup")) | ||
return redirect(url_for("admin.install")) | ||
|
||
|
||
def template_filters(app): | ||
@app.template_filter("friendly_time") | ||
def friendly_time(date): | ||
now = datetime.now() | ||
delta = now - date | ||
if delta.days >= 365: | ||
return u'%d年前' % (delta.days / 365) | ||
elif delta.days >= 30: | ||
return u'%d个月前' % (delta.days / 30) | ||
elif delta.days > 0: | ||
return u'%d天前' % delta.days | ||
elif delta.days < 0: | ||
return u"0秒前" | ||
elif delta.seconds < 60: | ||
return u"%d秒前" % delta.seconds | ||
elif delta.seconds < 60 * 60: | ||
return u"%d分钟前" % (delta.seconds / 60) | ||
else: | ||
return u"%d小时前" % (delta.seconds / 60 / 60) | ||
|
||
|
||
def create_app(): | ||
app = Flask(__name__) | ||
app.config.from_object(DefaultConfig) | ||
|
||
from models.model import db, login_manager | ||
|
||
bootstrap.init_app(app) | ||
db.init_app(app) | ||
db.PREFIX = app.config["DB_PREFIX"] | ||
|
||
app.site = {} | ||
def site_context_processor(): | ||
return dict(site=app.site) | ||
app.context_processor(site_context_processor) | ||
check_start(app, db) | ||
|
||
login_manager.init_app(app) | ||
|
||
from app.web import web | ||
app.register_blueprint(web) | ||
|
||
from app.admin import admin | ||
app.register_blueprint(admin, url_prefix="/admin") | ||
|
||
from app.api import api | ||
app.register_blueprint(api, url_prefix="/api") | ||
|
||
template_filters(app) | ||
|
||
login_manager.login_view = "admin.login" | ||
login_manager.login_message = "请先登录!!!" | ||
|
||
from app.log import init_logging | ||
init_logging(app) | ||
|
||
return app | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#coding:utf-8 | ||
from flask import Blueprint | ||
admin = Blueprint("admin", __name__) | ||
|
||
import app.admin.views | ||
|
||
from app.models import site |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#coding: utf-8 | ||
from flask.ext.wtf import Form | ||
from wtforms import StringField,RadioField | ||
from wtforms import TextAreaField | ||
from wtforms.validators import DataRequired, Length | ||
|
||
|
||
|
||
class BookForm(Form): | ||
name = StringField("书名", validators=[DataRequired("书名不能为空"), Length(1, 125, "长度不能超过125个字符")]) | ||
brief = TextAreaField("描述") | ||
access = RadioField("访问权限", choices=[("1", "公开"), ("private", "私人")]) | ||
|
||
|
||
class SettingForm(Form): | ||
name = StringField("书名", validators=[DataRequired("书名不能为空"), Length(1, 125, "长度不能超过125个字符")]) | ||
brief = TextAreaField("描述") | ||
access = RadioField("访问权限", choices=[("1", "公开"), ("0", "私人")]) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
#coding: utf-8 | ||
from flask.ext.wtf import Form | ||
from wtforms import StringField | ||
from wtforms import TextAreaField | ||
from wtforms.validators import DataRequired, Length | ||
|
||
|
||
class SiteForm(Form): | ||
name = StringField("名称", validators=[DataRequired("网站名称不能为空"), Length(1, 125, "长度不能超过125个字符")]) | ||
description = StringField("一句话描述", validators=[Length(0, 125, "长度不能超过125个字符")]) | ||
about = TextAreaField("关于本站") | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
#coding: utf-8 | ||
from flask.ext.wtf import Form | ||
from wtforms import StringField, PasswordField, BooleanField | ||
from wtforms.validators import DataRequired, Length | ||
|
||
|
||
class ConfigForm(Form): | ||
db = StringField("数据库名称", validators=[DataRequired("数据库名称不能为空")]) | ||
username = StringField("用户名", validators=[DataRequired("用户名不能为空")]) | ||
password = StringField("密码") | ||
host = StringField("数据库主机", validators=[DataRequired("数据库主机不能为空")]) | ||
|
||
|
||
class InstallForm(Form): | ||
name = StringField("网站名称", validators=[DataRequired("网站名称不能为空")]) | ||
username = StringField("用户名", validators=[DataRequired("用户名不能为空"), | ||
Length(3, 50, "用户长度在3到50个字符之间")]) | ||
password = PasswordField("密码", validators=[DataRequired("密码不能为空"), | ||
Length(6, 128, "密码长度应该在6到128个字符之间")]) | ||
|
||
|
||
class LoginForm(Form): | ||
username = StringField("用户名", validators=[DataRequired("用户名不能为空")]) | ||
password = PasswordField("密码", validators=[DataRequired("密码不能为空")]) | ||
remember = BooleanField("记住我") | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#coding: utf-8 | ||
from flask.ext.wtf import Form | ||
from wtforms import StringField, PasswordField | ||
from wtforms.validators import DataRequired, Length | ||
|
||
|
||
class UserForm(Form): | ||
username = StringField("用户名", validators=[DataRequired("用户名不能为空"), | ||
Length(3, 50, "用户名长度在3到50个字符之间")]) | ||
password = PasswordField("密码", validators=[DataRequired("密码不能为空"), | ||
Length(6, 128, "密码长度应该在6到128个字符之间")]) | ||
|
||
|
||
class SettingForm(Form): | ||
nickname = StringField("昵称", validators=[DataRequired("昵称不能为空"), | ||
Length(1, 50, "昵称长度在1到50个字符之间")]) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#coding:utf-8 | ||
|
||
import app.admin.views.start | ||
import app.admin.views.book | ||
import app.admin.views.user | ||
import app.admin.views.site | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
#coding: utf-8 | ||
from flask import current_app, render_template, request, redirect,\ | ||
url_for, abort, flash | ||
from flask_login import login_required, current_user | ||
from app.admin import admin | ||
from app.admin.forms.book import * | ||
from app.models.book import * | ||
|
||
|
||
@admin.route("/") | ||
@login_required | ||
def index(): | ||
page = request.args.get("page", 1, type=int) | ||
per_page = current_app.config["PER_PAGE"] | ||
tab = request.args.get("tab", "book") | ||
count_draft = current_user.count_draft() | ||
if tab=="draft": | ||
books = current_user.page_draft(page, per_page) | ||
else: | ||
books = current_user.page_book(page, per_page) | ||
return render_template("admin/book/index.html", books = books, | ||
count_draft=count_draft, tab=tab) | ||
|
||
|
||
@admin.route("/book/new", methods=["GET", "POST"]) | ||
@login_required | ||
def book_new(): | ||
form = BookForm() | ||
if form.validate_on_submit(): | ||
book = Book.add(form.name.data, form.brief.data, | ||
form.access.data, current_user.id) | ||
return redirect(url_for("admin.book_edit", id=book.id)) | ||
return render_template("admin/book/new.html", form=form) | ||
|
||
|
||
@admin.route("/book/<int:id>", methods=["GET", "POST"]) | ||
@login_required | ||
def book_detail(id): | ||
book = Book.get(id) | ||
if not book: | ||
return abort(404) | ||
form = SettingForm() | ||
if form.validate_on_submit(): | ||
book.setting(form.name.data, form.brief.data, form.access.data) | ||
flash("设置成功") | ||
return render_template("admin/book/detail.html", book = book, form=form) | ||
|
||
|
||
@admin.route("/book/<int:id>/edit") | ||
@login_required | ||
def book_edit(id): | ||
book = Book.get(id) | ||
if not book: | ||
return abort(404) | ||
return render_template("admin/book/edit.html", book = book) | ||
|
||
|
||
@admin.route("/catalog/<int:id>/change") | ||
@login_required | ||
def catalog_change(id): | ||
catalog = BookCatalog.get(id) | ||
if catalog.is_dir or catalog.book.user_id != current_user.id: | ||
return abort(404) | ||
catalog.is_dir = True | ||
return redirect(url_for("admin.book_edit", id=catalog.book_id)) | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#coding: utf-8 | ||
from flask import current_app, render_template, flash | ||
from flask_login import login_required | ||
from app.admin import admin | ||
from app.includes.start import set_site | ||
from app.admin.forms.site import * | ||
from app.models.site import * | ||
|
||
|
||
@admin.route("/site", methods=["GET", "POST"]) | ||
@login_required | ||
def site(): | ||
form = SiteForm() | ||
if form.validate_on_submit(): | ||
metas = { | ||
"name": form.name.data, | ||
"description": form.description.data, | ||
"about": form.about.data | ||
} | ||
SiteMeta.setting(metas) | ||
flash("设置成功") | ||
set_site(current_app) | ||
metas = SiteMeta.all() | ||
site = dict([(meta.name, meta.value) for meta in metas]) | ||
return render_template("admin/site/site.html", form=form, site=site) | ||
|
Oops, something went wrong.