Skip to content
This repository has been archived by the owner on Jul 20, 2019. It is now read-only.

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
bbruceyuan committed Jul 12, 2018
0 parents commit ef7c9f3
Show file tree
Hide file tree
Showing 12 changed files with 522 additions and 0 deletions.
130 changes: 130 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# 一些别的东西
.idea
*.sqlite

# 加上vue文件家中的东西,也需要忽略,不过这里需要我们自己把它放过来

.DS_Store
# 这个需要添加frontend
frontend/node_modules/
front/dist/
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln

# 我的helloworld.py的学习文件,不用上传,反正应该也没人把文件名弄成helloworld.py吧
helloworld.py

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/

# Translations
*.mo
*.pot

# Django stuff:
*.log
.static_storage/
.media/
local_settings.py

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# Jupyter Notebook
.ipynb_checkpoints

# pyenv
.python-version

# celery beat schedule file
celerybeat-schedule

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
30 changes: 30 additions & 0 deletions backend/app/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/usr/bin/env python
# Created by BBruceyuan on 18-7-5.


from flask import Flask
from config import config

from flask_sqlalchemy import SQLAlchemy
from flask_cors import CORS


db = SQLAlchemy()


def create_app(config_name):
"""
based on config_name 创建不同的app
:param config_name:
:return:
"""
app = Flask(__name__)
# 如果是开发环境,要求跨域
if config_name == 'develop':
CORS(app) # or cors = CORS(app)
app.config.from_object(config[config_name])

# init backend config by a static method
config[config_name].init_app(app)
db.init_app(app)
return app
9 changes: 9 additions & 0 deletions backend/app/api/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env python
# Created by BBruceyuan on 18-7-11.


from flask import Blueprint

api = Blueprint('api', __name__)


64 changes: 64 additions & 0 deletions backend/app/api/authentication.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#!/usr/bin/env python
# Created by BBruceyuan on 18-7-11.


from flask import g, jsonify
from flask_httpauth import HTTPBasicAuth
from ..model import User
from . import api
from .errors import unauthorized


auth = HTTPBasicAuth()


@auth.verify_password
def verify_password(username_or_token, password):
"""
这获取的是头部中auth中的值
:param username_or_token:
:param password:
:return:
"""
if username_or_token == '':
return False
if password == '':
# 使用token进行验证
# 这时候说明是一个token, 而不是username
# 看User的实现可以知道,我们返回的是一个user
g.current_user = User.verify_auth_token(username_or_token)
g.token_used = True
return g.current_user is not None
user = User.query.get(username=username_or_token)
if not user:
return False
g.current_user = user
g.token_used = False
return g.current_user.verify_password(password)


@auth.error_handler
def auth_error():
return unauthorized('Invalid credentials')


# todo, 好好研究一下这个怎么放比较好
# 这个before_request仅仅对api下的路由生效
@api.before_request
@auth.login_required
def before_request():
"""
这么做的作用就是让api下所有的路由都需要auth.login_required
:return:
"""
pass


@api.route('/token')
def get_token():
# 因为g.current_user.generate_auth.token是一个byte值,所以需要decode
data = {
'token': g.current_user.generate_auth_token(expiration=3600).decode('utf-8'),
'expiration': 3600
}
return jsonify(data)
25 changes: 25 additions & 0 deletions backend/app/api/errors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/usr/bin/env python
# Created by BBruceyuan on 18-7-11.


from flask import jsonify


# todo, not used yet
def bad_request(message):
response = jsonify({'error': 'bad request', 'message': message})
response.status_code = 400
return response


def unauthorized(message):
response = jsonify({'error': 'unauthorized', 'message': message})
response.status_code = 401
return response


# todo, not used yet
def forbidden(message):
response = jsonify({'error': 'forbidden', 'message': message})
response.status_code = 403
return response
27 changes: 27 additions & 0 deletions backend/app/api/post.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/env python
# Created by BBruceyuan on 18-7-12.

from .. import db
from . import api
from ..model import Post
from flask import current_app, request, url_for, jsonify


@api.route('/posts/')
def get_posts():
page = request.args.get('page', 1, type=int)
pagination = Post.query.paginate(page, per_page=current_app.config['FLASKY_POSTS_PER_PAGE'], error_out=False)
posts = pagination.items
prev = None
if pagination.has_prev:
prev = url_for('api.get_posts', page=page - 1)
next_ = None
if pagination.has_next:
next_ = url_for('api.get_posts', page=page + 1)
return jsonify(
{
'posts': [post.to_json() for post in posts],
'prev': prev,
'next': next_,
'count': pagination.total
})
73 changes: 73 additions & 0 deletions backend/app/api/user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#!/usr/bin/env python
# Created by BBruceyuan on 18-7-12.

from flask import jsonify, request, url_for, current_app
from ..model import User, Post
from . import api
from .. import db


@api.route('/users/<uid>', methods=['GET', 'DELETE'])
def get_user(uid):
uu = UserUtils(uid)
if request.method == 'GET':
return uu.get_user()
elif request.method == 'DELETE':
return uu.del_user()


@api.route('/users/<uid>/posts/')
def get_user_posts(uid):
user = User.query.get_or_404(uid)
page = request.args.get('page', 1, type=int)
# 时间递减
pagination = user.posts.order_by(
Post.timestamp.desc()
).paginate(
page,
per_page=current_app.config['FLASK_POSTS_PER_PAGE'],
error_out=False)
posts = pagination.items
# 前面是否有请求过pagination, (previous)
prev = None
if pagination.has_prev:
prev = url_for('api.get_user_posts', id=uid, page=page - 1)
# 因为next是关键字,所以这里使用next_代替
next_ = None
if pagination.has_next:
next_ = url_for('api.get_user_posts', id=uid, page=page + 1)
return jsonify(
{
'posts': [post.to_json() for post in posts],
'prev': prev,
'next': next_,
'count': pagination.total
}
)


# @api.route('/user/<int:id>/timeline/')


class UserUtils:
"""
CRUD HTTP 对应http操作
Create POST  (这个是register
Read GET
Update PUT
Delete DELETE
"""
def __init__(self, user_id):
self.uid = user_id
self.user = User.query.get_or_404(self.uid)

def get_user(self):
return jsonify(self.user.to_json())

def del_user(self):
username = self.user.username
user = User.query.filter_by(username=username).first()
db.session.delete(user)
db.commit()
response = {"username": username, 'type': 'delete', 'error_code': 0}
return jsonify(response)
5 changes: 5 additions & 0 deletions backend/app/model/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env python
# Created by BBruceyuan on 18-7-5.

from .user import User
from .post import Post
23 changes: 23 additions & 0 deletions backend/app/model/post.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env python
# Created by BBruceyuan on 18-7-5.


from .. import db
import datetime


class Post(db.Model):
"""
post
"""
__tablename__ = 'posts'

id = db.Column(db.String(64), primary_key=True)
body = db.Column(db.Text)
body_html = db.Column(db.Text)
timestamp = db.Column(db.DateTime, index=True, default=datetime.datetime.utcnow)
author_id = db.Column(db.Integer, db.ForeignKey('users.id'))
# 加上author,这样就可以根据文章找作者,也可以直接更具作者找文章
author = db.relationship('User', backref='posts', lazy='dynamic')
# todo, 这个暂时不加
# comments = db.relationship('Comment', backref='post', lazy='dynamic')
Loading

0 comments on commit ef7c9f3

Please sign in to comment.