parent
d115eb47b6
commit
6d3a47dbae
@ -1,60 +1,147 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
import flask
|
import flask
|
||||||
import flask_cors
|
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 = 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)
|
flask_cors.CORS(app)
|
||||||
|
|
||||||
Base.metadata.create_all(engine)
|
|
||||||
|
class Quote(db.Model):
|
||||||
|
__tablename__ = 'quotes'
|
||||||
@app.route('/quotes')
|
|
||||||
def get_quotes():
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
args = flask.request.args
|
video_id = db.Column(db.Integer)
|
||||||
filter = args.get('filter', type=str)
|
date = db.Column(db.Date)
|
||||||
sort_by = args.get('sort_by', type=str)
|
game = db.Column(db.String)
|
||||||
sort_order = args.get('sort_order', type=str)
|
text = db.Column(db.String)
|
||||||
page_number = args.get('page_number', type=int)
|
created_at = db.Column(db.DateTime)
|
||||||
page_size = args.get('page_size', type=int)
|
updated_at = db.Column(db.DateTime)
|
||||||
session = Session()
|
|
||||||
try:
|
|
||||||
q = session.query(Quote)
|
quote_fields = {
|
||||||
if filter:
|
'id': flask_restful.fields.Integer(),
|
||||||
q = q.filter(Quote.text.ilike('%{}%'.format(filter)))
|
'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()
|
count = q.count()
|
||||||
if sort_by:
|
if args['sort_by']:
|
||||||
col = getattr(Quote, sort_by, None)
|
col = getattr(Quote, args['sort_by'], None)
|
||||||
if col:
|
if col:
|
||||||
if sort_order:
|
if args['sort_order']:
|
||||||
order_by = getattr(col, sort_order, None)
|
order_by = getattr(col, args['sort_order'], None)
|
||||||
if order_by:
|
if order_by:
|
||||||
q = q.order_by(order_by())
|
q = q.order_by(order_by())
|
||||||
else:
|
else:
|
||||||
q = q.order_by(col)
|
q = q.order_by(col)
|
||||||
if page_size:
|
if args['page_size']:
|
||||||
q = q.limit(page_size)
|
q = q.limit(args['page_size'])
|
||||||
if page_number and page_size:
|
if args['page_number'] and args['page_size']:
|
||||||
q = q.offset(page_number * page_size)
|
q = q.offset(args['page_number'] * args['page_size'])
|
||||||
data = QuoteSchema(many=True).dump(q).data
|
quotes = q.all()
|
||||||
finally:
|
return quotes, 200, {'X-Total-Count': count}
|
||||||
session.close()
|
|
||||||
return flask.jsonify(data), 200, {'X-Total-Count': count}
|
@flask_restful.marshal_with(quote_fields)
|
||||||
|
def post(self):
|
||||||
|
args = quote_parser.parse_args()
|
||||||
@app.route('/quotes', methods=['POST'])
|
if not args['id']:
|
||||||
def add_quote():
|
flask_restful.abort(400, message='Missing required parameter id')
|
||||||
q = QuoteSchema().load(flask.request.get_json())
|
now = sqlalchemy.func.now()
|
||||||
quote = Quote(**q.data)
|
q = db.session.query(Quote).filter(Quote.id == args['id'])
|
||||||
session = Session()
|
quote = q.first()
|
||||||
try:
|
if not quote:
|
||||||
session.add(quote)
|
quote = Quote(id=args['id'], created_at=now)
|
||||||
session.commit()
|
quote.video_id = args['video_id'] # FIXME: NULL
|
||||||
data = QuoteSchema().dump(quote).data
|
quote.date = args['date']
|
||||||
except:
|
quote.game = args['game']
|
||||||
session.rollback()
|
quote.text = args['text']
|
||||||
raise
|
quote.updated_at = now
|
||||||
finally:
|
db.session.add(quote)
|
||||||
session.close()
|
db.session.commit()
|
||||||
return flask.jsonify(data), 201
|
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