parent
d115eb47b6
commit
6d3a47dbae
@ -1,60 +1,147 @@
|
||||
import os
|
||||
|
||||
import flask
|
||||
import flask_cors
|
||||
import flask_restful
|
||||
import flask_restful.fields
|
||||
import flask_restful.reqparse
|
||||
import flask_sqlalchemy
|
||||
import sqlalchemy
|
||||
|
||||
from quote import engine, Base, Session, Quote, QuoteSchema
|
||||
|
||||
DB_PATH = os.path.expandvars('$HOME/quotes/quotes.db')
|
||||
|
||||
app = flask.Flask(__name__)
|
||||
app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{DB_PATH}'
|
||||
app.config['ERROR_404_HELP'] = False
|
||||
|
||||
db = flask_sqlalchemy.SQLAlchemy(app)
|
||||
db.create_all()
|
||||
|
||||
api = flask_restful.Api(app)
|
||||
|
||||
flask_cors.CORS(app)
|
||||
|
||||
Base.metadata.create_all(engine)
|
||||
|
||||
|
||||
@app.route('/quotes')
|
||||
def get_quotes():
|
||||
args = flask.request.args
|
||||
filter = args.get('filter', type=str)
|
||||
sort_by = args.get('sort_by', type=str)
|
||||
sort_order = args.get('sort_order', type=str)
|
||||
page_number = args.get('page_number', type=int)
|
||||
page_size = args.get('page_size', type=int)
|
||||
session = Session()
|
||||
try:
|
||||
q = session.query(Quote)
|
||||
if filter:
|
||||
q = q.filter(Quote.text.ilike('%{}%'.format(filter)))
|
||||
|
||||
class Quote(db.Model):
|
||||
__tablename__ = 'quotes'
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
video_id = db.Column(db.Integer)
|
||||
date = db.Column(db.Date)
|
||||
game = db.Column(db.String)
|
||||
text = db.Column(db.String)
|
||||
created_at = db.Column(db.DateTime)
|
||||
updated_at = db.Column(db.DateTime)
|
||||
|
||||
|
||||
quote_fields = {
|
||||
'id': flask_restful.fields.Integer(),
|
||||
'video_id': flask_restful.fields.Integer(),
|
||||
'date': flask_restful.fields.DateTime(dt_format='iso8601'),
|
||||
'game': flask_restful.fields.String(),
|
||||
'text': flask_restful.fields.String(),
|
||||
'created_at': flask_restful.fields.DateTime(dt_format='iso8601'),
|
||||
'updated_at': flask_restful.fields.DateTime(dt_format='iso8601'),
|
||||
}
|
||||
|
||||
|
||||
quote_parser = flask_restful.reqparse.RequestParser()
|
||||
quote_parser.add_argument('id', type=int)
|
||||
quote_parser.add_argument('video_id', type=int)
|
||||
quote_parser.add_argument('date', type=flask_restful.inputs.date, required=True)
|
||||
quote_parser.add_argument('game', type=str, required=True)
|
||||
quote_parser.add_argument('text', type=str, required=True)
|
||||
|
||||
|
||||
filter_parser = flask_restful.reqparse.RequestParser()
|
||||
filter_parser.add_argument('filter', type=str)
|
||||
filter_parser.add_argument('sort_by', type=str)
|
||||
filter_parser.add_argument('sort_order', type=str)
|
||||
filter_parser.add_argument('page_number', type=int)
|
||||
filter_parser.add_argument('page_size', type=int)
|
||||
|
||||
|
||||
class QuoteResource(flask_restful.Resource):
|
||||
@flask_restful.marshal_with(quote_fields)
|
||||
def get(self, id):
|
||||
q = db.session.query(Quote).filter(Quote.id == id)
|
||||
quote = q.first()
|
||||
if not quote:
|
||||
flask_restful.abort(404, message='Quote {0} does not exist'.format(id))
|
||||
return quote, 200
|
||||
|
||||
@flask_restful.marshal_with(quote_fields)
|
||||
def put(self, id):
|
||||
args = quote_parser.parse_args()
|
||||
now = sqlalchemy.func.now()
|
||||
q = db.session.query(Quote).filter(Quote.id == id)
|
||||
quote = q.first()
|
||||
if not quote:
|
||||
quote = Quote(id=id, created_at=now)
|
||||
quote.video_id = args['video_id'] # FIXME: NULL
|
||||
quote.date = args['date']
|
||||
quote.game = args['game']
|
||||
quote.text = args['text']
|
||||
quote.updated_at = now
|
||||
db.session.add(quote)
|
||||
db.session.commit()
|
||||
return quote, 200
|
||||
|
||||
def delete(self, id):
|
||||
q = db.session.query(Quote).filter(Quote.id == id)
|
||||
quote = q.first()
|
||||
if not quote:
|
||||
flask_restful.abort(404, message='Quote {0} does not exist'.format(id))
|
||||
db.session.delete(quote)
|
||||
db.session.commit()
|
||||
return None, 204
|
||||
|
||||
|
||||
class QuotesResource(flask_restful.Resource):
|
||||
@flask_restful.marshal_with(quote_fields)
|
||||
def get(self):
|
||||
args = filter_parser.parse_args()
|
||||
q = db.session.query(Quote)
|
||||
if args['filter']:
|
||||
q = q.filter(Quote.text.ilike('%{}%'.format(args['filter'])))
|
||||
count = q.count()
|
||||
if sort_by:
|
||||
col = getattr(Quote, sort_by, None)
|
||||
if args['sort_by']:
|
||||
col = getattr(Quote, args['sort_by'], None)
|
||||
if col:
|
||||
if sort_order:
|
||||
order_by = getattr(col, sort_order, None)
|
||||
if args['sort_order']:
|
||||
order_by = getattr(col, args['sort_order'], None)
|
||||
if order_by:
|
||||
q = q.order_by(order_by())
|
||||
else:
|
||||
q = q.order_by(col)
|
||||
if page_size:
|
||||
q = q.limit(page_size)
|
||||
if page_number and page_size:
|
||||
q = q.offset(page_number * page_size)
|
||||
data = QuoteSchema(many=True).dump(q).data
|
||||
finally:
|
||||
session.close()
|
||||
return flask.jsonify(data), 200, {'X-Total-Count': count}
|
||||
|
||||
|
||||
@app.route('/quotes', methods=['POST'])
|
||||
def add_quote():
|
||||
q = QuoteSchema().load(flask.request.get_json())
|
||||
quote = Quote(**q.data)
|
||||
session = Session()
|
||||
try:
|
||||
session.add(quote)
|
||||
session.commit()
|
||||
data = QuoteSchema().dump(quote).data
|
||||
except:
|
||||
session.rollback()
|
||||
raise
|
||||
finally:
|
||||
session.close()
|
||||
return flask.jsonify(data), 201
|
||||
if args['page_size']:
|
||||
q = q.limit(args['page_size'])
|
||||
if args['page_number'] and args['page_size']:
|
||||
q = q.offset(args['page_number'] * args['page_size'])
|
||||
quotes = q.all()
|
||||
return quotes, 200, {'X-Total-Count': count}
|
||||
|
||||
@flask_restful.marshal_with(quote_fields)
|
||||
def post(self):
|
||||
args = quote_parser.parse_args()
|
||||
if not args['id']:
|
||||
flask_restful.abort(400, message='Missing required parameter id')
|
||||
now = sqlalchemy.func.now()
|
||||
q = db.session.query(Quote).filter(Quote.id == args['id'])
|
||||
quote = q.first()
|
||||
if not quote:
|
||||
quote = Quote(id=args['id'], created_at=now)
|
||||
quote.video_id = args['video_id'] # FIXME: NULL
|
||||
quote.date = args['date']
|
||||
quote.game = args['game']
|
||||
quote.text = args['text']
|
||||
quote.updated_at = now
|
||||
db.session.add(quote)
|
||||
db.session.commit()
|
||||
url = api.url_for(QuoteResource, id=quote.id, _external=True, _scheme='https')
|
||||
return quote, 201, {'Location': url}
|
||||
|
||||
|
||||
api.add_resource(QuoteResource, '/quotes/<int:id>')
|
||||
api.add_resource(QuotesResource, '/quotes')
|
||||
|
@ -1,48 +0,0 @@
|
||||
import os
|
||||
|
||||
import marshmallow
|
||||
import sqlalchemy
|
||||
import sqlalchemy.orm
|
||||
import sqlalchemy.ext.declarative
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
DB_PATH = os.path.expandvars('$HOME/quotes/quotes.db')
|
||||
|
||||
engine = sqlalchemy.create_engine(f'sqlite:///{DB_PATH}')
|
||||
Session = sqlalchemy.orm.sessionmaker(bind=engine)
|
||||
Base = sqlalchemy.ext.declarative.declarative_base()
|
||||
|
||||
|
||||
class Quote(Base):
|
||||
|
||||
__tablename__ = 'quotes'
|
||||
|
||||
id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True)
|
||||
video_id = sqlalchemy.Column(sqlalchemy.Integer)
|
||||
date = sqlalchemy.Column(sqlalchemy.Date)
|
||||
game = sqlalchemy.Column(sqlalchemy.String)
|
||||
text = sqlalchemy.Column(sqlalchemy.String)
|
||||
created_at = sqlalchemy.Column(sqlalchemy.DateTime)
|
||||
updated_at = sqlalchemy.Column(sqlalchemy.DateTime)
|
||||
|
||||
def __init__(self, id, video_id, date, game, text):
|
||||
self.id = id
|
||||
self.video_id = video_id
|
||||
self.date = date
|
||||
self.game = game
|
||||
self.text = text
|
||||
self.created_at = datetime.now()
|
||||
self.updated_at = datetime.now()
|
||||
|
||||
|
||||
class QuoteSchema(marshmallow.Schema):
|
||||
|
||||
id = marshmallow.fields.Integer()
|
||||
video_id = marshmallow.fields.Integer()
|
||||
date = marshmallow.fields.Date()
|
||||
game = marshmallow.fields.Str()
|
||||
text = marshmallow.fields.Str()
|
||||
created_at = marshmallow.fields.DateTime()
|
||||
updated_at = marshmallow.fields.DateTime()
|
Loading…
Reference in new issue