|
from datetime import datetime |
|
from hashlib import md5 |
|
import time |
|
|
|
from werkzeug.security import generate_password_hash, check_password_hash |
|
|
|
from flask_login import UserMixin |
|
from flask import current_app |
|
import jwt |
|
|
|
from detectweb import db, login_manager |
|
from detectweb.models.tweet import Tweet |
|
from detectweb.models.predict import Predict |
|
|
|
|
|
followers = db.Table('followers', |
|
db.Column('follower_id', db.Integer, db.ForeignKey('user.id')), |
|
db.Column('followed_id', db.Integer, db.ForeignKey('user.id')) |
|
) |
|
|
|
|
|
class User(UserMixin, db.Model): |
|
id = db.Column(db.Integer, primary_key=True) |
|
username = db.Column(db.String(64), unique=True, index=True) |
|
email = db.Column(db.String(64), unique=True, index=True) |
|
country = db.Column(db.String(20)) |
|
province = db.Column(db.String(20)) |
|
city = db.Column(db.String(20)) |
|
password_hash = db.Column(db.String(128)) |
|
about_me = db.Column(db.String(120)) |
|
create_time = db.Column(db.DateTime, default=datetime.utcnow) |
|
is_activated = db.Column(db.Boolean, default=False) |
|
|
|
|
|
tweets = db.relationship('Tweet', backref='author', lazy='dynamic') |
|
predicts = db.relationship('Predict', backref='author', lazy='dynamic') |
|
|
|
|
|
|
|
followed = db.relationship( |
|
'User', secondary=followers, |
|
primaryjoin=(followers.c.follower_id == id), |
|
secondaryjoin=(followers.c.followed_id == id), |
|
backref=db.backref('followers', lazy='dynamic'), lazy='dynamic') |
|
|
|
def __repr__(self): |
|
return 'id={}, username={}, email={}, password_hash={}'.format( |
|
self.id, self.username, self.email, self.password_hash |
|
) |
|
|
|
def set_password(self, password): |
|
self.password_hash = generate_password_hash(password) |
|
|
|
def check_password(self, password): |
|
return check_password_hash(self.password_hash, password) |
|
|
|
|
|
def avatar(self, size=80): |
|
md5_digest = md5(self.email.lower().encode('utf-8')).hexdigest() |
|
return 'https://cdn.v2ex.com/gravatar/{}?d=identicon&s={}'.format( |
|
md5_digest, size) |
|
|
|
|
|
def follow(self, user): |
|
if not self.is_following(user): |
|
self.followed.append(user) |
|
|
|
|
|
def unfollow(self, user): |
|
if self.is_following(user): |
|
self.followed.remove(user) |
|
|
|
|
|
def is_following(self, user): |
|
return self.followed.filter( |
|
followers.c.followed_id == user.id).count() > 0 |
|
|
|
|
|
def own_and_followed_tweets(self): |
|
|
|
|
|
followed = Tweet.query.join( |
|
followers, (followers.c.followed_id == Tweet.user_id)).filter( |
|
followers.c.follower_id == self.id) |
|
own = Tweet.query.filter_by(user_id=self.id) |
|
|
|
return followed.union(own).order_by(Tweet.create_time.desc()) |
|
|
|
|
|
def get_jwt(self, expire=7200): |
|
return jwt.encode( |
|
{ |
|
'email': self.email, |
|
'exp': time.time() + expire |
|
}, |
|
current_app.config['SECRET_KEY'], |
|
algorithm='HS256' |
|
).decode('utf-8') |
|
|
|
""" |
|
想直接通过User class来使用,而不是先实例化一个 |
|
""" |
|
@staticmethod |
|
def verify_jwt(token): |
|
|
|
try: |
|
email = jwt.decode( |
|
token, |
|
current_app.config['SECRET_KEY'], |
|
algorithms=['HS256'] |
|
) |
|
email = email['email'] |
|
except: |
|
return |
|
|
|
return User.query.filter_by(email=email).first() |
|
|
|
|
|
@login_manager.user_loader |
|
def load_user(id): |
|
return User.query.get(int(id)) |
|
|
|
""" |
|
国内Gravatar镜像源收集 |
|
gravatar官方的www https://www.gravatar.com/avatar/ |
|
gravatar官方的cn https://cn.gravatar.com/avatar/ |
|
gravatar官方的en https://en.gravatar.com/avatar/ |
|
gravatar官方的secure https://secure.gravatar.com/avatar/ |
|
V2EX https://cdn.v2ex.com/gravatar/ |
|
Loli https://gravatar.loli.net/avatar/ |
|
极客族 https://sdn.geekzu.org/avatar/ |
|
Zeruns's Blog:https://gravatar.zeruns.tech/avatar/ |
|
宝硕博客:https://gravatar.baoshuo.ren/avatar |
|
左岸博客源:https://avatar.zrahh.com/avatar |
|
""" |