from flask import Flask from flask import request import config import database import utils app = Flask(__name__) calendar_db = database.CalendarDatabase() # region: API Route # region: Common @app.route('/common/salt', methods=['POST']) def api_common_saltHandle(): return SmartDbCaller(calendar_db.common_salt, (('username', str, False), ), None) @app.route('/common/login', methods=['POST']) def api_common_loginHandle(): # construct client data first clientUa = request.user_agent.string if request.headers.getlist("X-Forwarded-For"): clientIp = request.headers.getlist("X-Forwarded-For")[0] else: clientIp = request.remote_addr return SmartDbCaller(calendar_db.common_login, (('username', str, False), ('password', str, False), ('clientUa', str, False), ('clientIp', str, False)), { 'clientUa': clientUa, 'clientIp': clientIp }) @app.route('/common/webLogin', methods=['POST']) def api_common_webLoginHandle(): # construct client data first clientUa = request.user_agent.string if request.headers.getlist("X-Forwarded-For"): clientIp = request.headers.getlist("X-Forwarded-For")[0] else: clientIp = request.remote_addr return SmartDbCaller(calendar_db.common_webLogin, (('username', str, False), ('password', str, False), ('clientUa', str, False), ('clientIp', str, False)), { 'clientUa': clientUa, 'clientIp': clientIp }) @app.route('/common/logout', methods=['POST']) def api_common_logoutHandle(): return SmartDbCaller(calendar_db.common_logout, (('token', str, False), ), None) @app.route('/common/tokenValid', methods=['POST']) def api_common_tokenValidHandle(): return SmartDbCaller(calendar_db.common_tokenValid, (('token', str, False), ), None) # endregion # region: Calendar @app.route('/calendar/getFull', methods=['POST']) def api_calendar_getFullHandle(): return SmartDbCaller(calendar_db.calendar_getFull, (('token', str, False), ('startDateTime', int, False), ('endDateTime', int, False)), None) @app.route('/calendar/getList', methods=['POST']) def api_calendar_getListHandle(): return SmartDbCaller(calendar_db.calendar_getList, (('token', str, False), ('startDateTime', int, False), ('endDateTime', int, False)), None) @app.route('/calendar/getDetail', methods=['POST']) def api_calendar_getDetailHandle(): return SmartDbCaller(calendar_db.calendar_getDetail, (('token', str, False), ('uuid', str, False)), None) @app.route('/calendar/update', methods=['POST']) def api_calendar_updateHandle(): return SmartDbCaller(calendar_db.calendar_update, (('token', str, False), ('uuid', str, False), ('belongTo', str, True), ('title', str, True), ('description', str, True), ('eventDateTimeStart', int, True), ('eventDateTimeEnd', int, True), ('loopRules', str, True), ('timezoneOffset', int, True), ('lastChange', str, False)), None) @app.route('/calendar/add', methods=['POST']) def api_calendar_addHandle(): return SmartDbCaller(calendar_db.calendar_add, (('token', str, False), ('belongTo', str, False), ('title', str, False), ('description', str, False), ('eventDateTimeStart', int, False), ('eventDateTimeEnd', int, False), ('loopRules', str, False), ('timezoneOffset', int, False)), None) @app.route('/calendar/delete', methods=['POST']) def api_calendar_deleteHandle(): return SmartDbCaller(calendar_db.calendar_delete, (('token', str, False), ('uuid', str, False), ('lastChange', str, False)), None) # endregion # region: Collection @app.route('/collection/getFullOwn', methods=['POST']) def api_collection_getFullOwnHandle(): return SmartDbCaller(calendar_db.collection_getFullOwn, (('token', str, False), ), None) @app.route('/collection/getListOwn', methods=['POST']) def api_collection_getListOwnHandle(): return SmartDbCaller(calendar_db.collection_getListOwn, (('token', str, False), ), None) @app.route('/collection/getDetailOwn', methods=['POST']) def api_collection_getDetailOwnHandle(): return SmartDbCaller(calendar_db.collection_getDetailOwn, (('token', str, False), ('uuid', str, False)), None) @app.route('/collection/addOwn', methods=['POST']) def api_collection_addOwnHandle(): return SmartDbCaller(calendar_db.collection_addOwn, (('token', str, False), ('name', str, False)), None) @app.route('/collection/updateOwn', methods=['POST']) def api_collection_updateOwnHandle(): return SmartDbCaller(calendar_db.collection_updateOwn, (('token', str, False), ('uuid', str, False), ('name', str, False), ('lastChange', str, False)), None) @app.route('/collection/deleteOwn', methods=['POST']) def api_collection_deleteOwnHandle(): return SmartDbCaller(calendar_db.collection_deleteOwn, (('token', str, False), ('uuid', str, False), ('lastChange', str, False)), None) @app.route('/collection/getSharing', methods=['POST']) def api_collection_getSharingHandle(): return SmartDbCaller(calendar_db.collection_getSharing, (('token', str, False), ('uuid', str, False)), None) @app.route('/collection/deleteSharing', methods=['POST']) def api_collection_deleteSharingHandle(): return SmartDbCaller(calendar_db.collection_deleteSharing, (('token', str, False), ('uuid', str, False), ('target', str, False), ('lastChange', str, False)), None) @app.route('/collection/addSharing', methods=['POST']) def api_collection_addSharingHandle(): return SmartDbCaller(calendar_db.collection_addSharing, (('token', str, False), ('uuid', str, False), ('target', str, False), ('lastChange', str, False)), None) @app.route('/collection/getShared', methods=['POST']) def api_collection_getSharedHandle(): return SmartDbCaller(calendar_db.collection_getShared, (('token', str, False), ), None) # endregion # region: Todo @app.route('/todo/getFull', methods=['POST']) def api_todo_getFullHandle(): return SmartDbCaller(calendar_db.todo_getFull, (('token', str, False), ), None) @app.route('/todo/getList', methods=['POST']) def api_todo_getListHandle(): return SmartDbCaller(calendar_db.todo_getList, (('token', str, False), ), None) @app.route('/todo/getDetail', methods=['POST']) def api_todo_getDetailHandle(): return SmartDbCaller(calendar_db.todo_getDetail, (('token', str, False), ('uuid', str, False)), None) @app.route('/todo/add', methods=['POST']) def api_todo_addHandle(): return SmartDbCaller(calendar_db.todo_add, (('token', str, False), ), None) @app.route('/todo/update', methods=['POST']) def api_todo_updateHandle(): return SmartDbCaller(calendar_db.todo_update, (('token', str, False), ('uuid', str, False), ('data', str, False), ('lastChange', str, False)), None) @app.route('/todo/delete', methods=['POST']) def api_todo_deleteHandle(): return SmartDbCaller(calendar_db.todo_delete, (('token', str, False), ('uuid', str, False), ('lastChange', str, False)), None) # endregion # region: Admin @app.route('/admin/get', methods=['POST']) def api_admin_getHandle(): return SmartDbCaller(calendar_db.admin_get, (('token', str, False), ), None) @app.route('/admin/add', methods=['POST']) def api_admin_addHandle(): return SmartDbCaller(calendar_db.admin_add, (('token', str, False), ('username', str, False)), None) @app.route('/admin/update', methods=['POST']) def api_admin_updateHandle(): return SmartDbCaller(calendar_db.admin_update, (('token', str, False), ('username', str, False), ('password', str, True), ('isAdmin', utils.Str2Bool, True)), None) @app.route('/admin/delete', methods=['POST']) def api_admin_deleteHandle(): return SmartDbCaller(calendar_db.admin_delete, (('token', str, False), ('username', str, False)), None) # endregion # region: Profile @app.route('/profile/isAdmin', methods=['POST']) def api_profile_isAdminHandle(): return SmartDbCaller(calendar_db.profile_isAdmin, (('token', str, False), ), None) @app.route('/profile/changePassword', methods=['POST']) def api_profile_changePasswordHandle(): return SmartDbCaller(calendar_db.profile_changePassword, (('token', str, False), ('password', str, False)), None) @app.route('/profile/getToken', methods=['POST']) def api_profile_getTokenHandle(): return SmartDbCaller(calendar_db.profile_getToken, (('token', str, False), ), None) @app.route('/profile/deleteToken', methods=['POST']) def api_profile_deleteTokenHandle(): return SmartDbCaller(calendar_db.profile_deleteToken, (('token', str, False), ('deleteToken', str, False)), None) # endregion # endregion # region: Misc Functions def SmartDbCaller(dbMethod, paramTuple, extraDict): result = (False, 'Invalid parameter', None) optCount = 0 paramList = [] optParamDict = {} # for each item, # item[0] is field name. # item[1] is type. # item[2] is whether it is optional field realForm = request.form.to_dict() if extraDict is not None: realForm.update(extraDict) for item in paramTuple: cache = item[1](realForm.get(item[0], None)) if item[2]: # optional param if cache is not None: optParamDict[item[0]] = cache optCount += 1 else: if cache is None: break paramList.append(cache) else: # at least one opt param if optCount == 0 or len(optParamDict) != 0: result = dbMethod(*paramList, **optParamDict) return ConstructResponseBody(result) def ConstructResponseBody(returnedTuple): return { 'success': returnedTuple[0], 'error': returnedTuple[1], 'data': returnedTuple[2] } def run(): calendar_db.open() app.run(port=config.get_config().web.port) calendar_db.close() # endregion