From c16ed9546b9ee619ec443037be3fefe22cba8475 Mon Sep 17 00:00:00 2001 From: azivner Date: Wed, 30 Aug 2017 23:07:45 -0400 Subject: [PATCH] got rid of flask_restful and using plain flask to handle REST API calls --- src/app.py | 27 ++----- src/expanded_note.py | 10 --- src/move_after_note.py | 15 ---- src/move_before_note.py | 15 ---- src/move_to_note.py | 19 ----- src/notes.py | 70 ------------------- src/notes_api.py | 151 ++++++++++++++++++++++++++++++++++++++++ src/notes_children.py | 64 ----------------- src/notes_move_api.py | 57 +++++++++++++++ src/notes_search.py | 18 ----- src/tree.py | 40 ----------- src/tree_api.py | 43 ++++++++++++ 12 files changed, 257 insertions(+), 272 deletions(-) delete mode 100644 src/expanded_note.py delete mode 100644 src/move_after_note.py delete mode 100644 src/move_before_note.py delete mode 100644 src/move_to_note.py delete mode 100644 src/notes.py create mode 100644 src/notes_api.py delete mode 100644 src/notes_children.py create mode 100644 src/notes_move_api.py delete mode 100644 src/notes_search.py delete mode 100644 src/tree.py create mode 100644 src/tree_api.py diff --git a/src/app.py b/src/app.py index 1c4732cea..39e10350e 100644 --- a/src/app.py +++ b/src/app.py @@ -6,23 +6,20 @@ from flask import Flask, request, send_from_directory from flask import render_template, redirect from flask_cors import CORS from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user -from flask_restful import Api -from expanded_note import ExpandedNote -from move_after_note import MoveAfterNote -from move_before_note import MoveBeforeNote -from move_to_note import MoveToNote -from notes import Notes -from notes_children import NotesChildren -from notes_search import NotesSearch +from notes_api import notes_api from sql import connect -from tree import Tree +from tree_api import tree_api +from notes_move_api import notes_move_api config = configparser.ConfigParser() config.read('config.ini') app = Flask(__name__) app.secret_key = config['Security']['flaskSecretKey'] +app.register_blueprint(tree_api) +app.register_blueprint(notes_api) +app.register_blueprint(notes_move_api) class User(UserMixin): pass @@ -75,16 +72,6 @@ CORS(app) def send_stc(path): return send_from_directory(os.path.join(os.getcwd(), 'static'), path) -api = Api(app) - -api.add_resource(NotesChildren, '/notes//children') -api.add_resource(MoveAfterNote, '/notes//moveAfter/') -api.add_resource(MoveBeforeNote, '/notes//moveBefore/') -api.add_resource(MoveToNote, '/notes//moveTo/') -api.add_resource(ExpandedNote, '/notes//expanded/') -api.add_resource(Tree, '/tree') -api.add_resource(NotesSearch, '/notes') - login_manager = LoginManager() login_manager.init_app(app) login_manager.login_view = 'login_form' @@ -96,8 +83,6 @@ def load_user(user_id): else: return None -api.add_resource(Notes, '/notes/') - if __name__ == "__main__": ssl_context = None diff --git a/src/expanded_note.py b/src/expanded_note.py deleted file mode 100644 index 0c620b635..000000000 --- a/src/expanded_note.py +++ /dev/null @@ -1,10 +0,0 @@ -from flask_restful import Resource - -from sql import execute, commit - - -class ExpandedNote(Resource): - def put(self, note_id, expanded): - execute("update notes_tree set is_expanded = ? where note_id = ?", [expanded, note_id]) - - commit() diff --git a/src/move_after_note.py b/src/move_after_note.py deleted file mode 100644 index 383073dcc..000000000 --- a/src/move_after_note.py +++ /dev/null @@ -1,15 +0,0 @@ -from flask_restful import Resource - -from sql import execute, getSingleResult, commit - - -class MoveAfterNote(Resource): - def put(self, note_id, after_note_id): - after_note = getSingleResult("select * from notes_tree where note_id = ?", [after_note_id]) - - if after_note <> None: - execute("update notes_tree set note_pos = note_pos + 1 where note_pid = ? and note_pos > ?", [after_note['note_pid'], after_note['note_pos']]) - - execute("update notes_tree set note_pid = ?, note_pos = ? where note_id = ?", [after_note['note_pid'], after_note['note_pos'] + 1, note_id]) - - commit() diff --git a/src/move_before_note.py b/src/move_before_note.py deleted file mode 100644 index c024bdf44..000000000 --- a/src/move_before_note.py +++ /dev/null @@ -1,15 +0,0 @@ -from flask_restful import Resource - -from sql import execute, getSingleResult, commit - - -class MoveBeforeNote(Resource): - def put(self, note_id, before_note_id): - before_note = getSingleResult("select * from notes_tree where note_id = ?", [before_note_id]) - - if before_note <> None: - execute("update notes_tree set note_pos = note_pos + 1 where note_id = ?", [before_note_id]) - - execute("update notes_tree set note_pid = ?, note_pos = ? where note_id = ?", [before_note['note_pid'], before_note['note_pos'], note_id]) - - commit() diff --git a/src/move_to_note.py b/src/move_to_note.py deleted file mode 100644 index 91e6af176..000000000 --- a/src/move_to_note.py +++ /dev/null @@ -1,19 +0,0 @@ -from flask_restful import Resource - -from sql import execute, getSingleResult, commit - - -class MoveToNote(Resource): - def put(self, note_id, parent_id): - res = getSingleResult('select max(note_pos) as max_note_pos from notes_tree where note_pid = ?', [parent_id]) - max_note_pos = res['max_note_pos'] - new_note_pos = 0 - - if max_note_pos is None: # no children yet - new_note_pos = 0 - else: - new_note_pos = max_note_pos + 1 - - execute("update notes_tree set note_pid = ?, note_pos = ? where note_id = ?", [parent_id, new_note_pos, note_id]) - - commit() \ No newline at end of file diff --git a/src/notes.py b/src/notes.py deleted file mode 100644 index 7635f4b3e..000000000 --- a/src/notes.py +++ /dev/null @@ -1,70 +0,0 @@ -import base64 -import math -import time - -from flask import request -from flask_restful import Resource - -from sql import delete, execute, insert, getResults, getSingleResult, commit - - -class Notes(Resource): - def get(self, note_id): - execute("update options set opt_value = ? where opt_name = 'start_node'", [note_id]) - - detail = getSingleResult("select * from notes where note_id = ?", [note_id]) - - if detail['note_clone_id']: - note_id = detail['note_clone_id'] - detail = getSingleResult("select * from notes where note_id = ?", [note_id]) - - return { - 'detail': detail, - 'formatting': getResults("select * from formatting where note_id = ? order by note_offset", [note_id]), - 'links': getResults("select * from links where note_id = ? order by note_offset", [note_id]), - 'images': getResults("select * from images where note_id = ? order by note_offset", [note_id]) - } - - def put(self, note_id): - detail = getSingleResult("select * from notes where note_id = ?", [note_id]) - - if detail['note_clone_id']: - note_id = detail['note_clone_id'] - - note = request.get_json(force=True) - - now = math.floor(time.time()) - - execute("update notes set note_text = ?, note_title = ?, date_modified = ? where note_id = ?", [note['detail']['note_text'], note['detail']['note_title'], now, note_id]) - - delete("formatting", note_id) - - for fmt in note['formatting']: - insert("formatting", fmt) - - delete("images", note_id) - - for img in note['images']: - img['image_data'] = buffer(base64.b64decode(img['image_data'])) - - insert("images", img) - - delete("links", note_id) - - for link in note['links']: - insert("links", link) - - commit() - - return {} - - def delete(self, note_id): - children = getResults("select note_id from notes_tree where note_pid = ?", [note_id]) - - for child in children: - self.delete(child['note_id']) - - delete("notes_tree", note_id) - delete("notes", note_id) - - commit() diff --git a/src/notes_api.py b/src/notes_api.py new file mode 100644 index 000000000..54325e72f --- /dev/null +++ b/src/notes_api.py @@ -0,0 +1,151 @@ +import base64 +import math +import random +import string +import time + +from flask import Blueprint, jsonify +from flask import request +from flask_login import login_required + +from sql import delete +from sql import execute, insert, commit +from sql import getResults, getSingleResult + +notes_api = Blueprint('notes_api', __name__) + +@notes_api.route('/notes/', methods = ['GET']) +@login_required +def getNote(note_id): + execute("update options set opt_value = ? where opt_name = 'start_node'", [note_id]) + + detail = getSingleResult("select * from notes where note_id = ?", [note_id]) + + if detail['note_clone_id']: + note_id = detail['note_clone_id'] + detail = getSingleResult("select * from notes where note_id = ?", [note_id]) + + return jsonify({ + 'detail': detail, + 'formatting': getResults("select * from formatting where note_id = ? order by note_offset", [note_id]), + 'links': getResults("select * from links where note_id = ? order by note_offset", [note_id]), + 'images': getResults("select * from images where note_id = ? order by note_offset", [note_id]) + }) + +@notes_api.route('/notes/', methods = ['PUT']) +@login_required +def updateNote(note_id): + detail = getSingleResult("select * from notes where note_id = ?", [note_id]) + + if detail['note_clone_id']: + note_id = detail['note_clone_id'] + + note = request.get_json(force=True) + + now = math.floor(time.time()) + + execute("update notes set note_text = ?, note_title = ?, date_modified = ? where note_id = ?", [note['detail']['note_text'], note['detail']['note_title'], now, note_id]) + + delete("formatting", note_id) + + for fmt in note['formatting']: + insert("formatting", fmt) + + delete("images", note_id) + + for img in note['images']: + img['image_data'] = buffer(base64.b64decode(img['image_data'])) + + insert("images", img) + + delete("links", note_id) + + for link in note['links']: + insert("links", link) + + commit() + + return jsonify({}) + +@notes_api.route('/notes/', methods = ['DELETE']) +@login_required +def deleteNote(note_id): + children = getResults("select note_id from notes_tree where note_pid = ?", [note_id]) + + for child in children: + delete(child['note_id']) + + delete("notes_tree", note_id) + delete("notes", note_id) + + commit() + return jsonify({}) + +@notes_api.route('/notes//children', methods = ['POST']) +@login_required +def createChild(parent_note_id): + note = request.get_json(force=True) + + noteId = ''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(22)) + + if parent_note_id == "root": + parent_note_id = "" + + new_note_pos = 0 + + if note['target'] == 'into': + res = getSingleResult('select max(note_pos) as max_note_pos from notes_tree where note_pid = ?', [parent_note_id]) + max_note_pos = res['max_note_pos'] + + if max_note_pos is None: # no children yet + new_note_pos = 0 + else: + new_note_pos = max_note_pos + 1 + elif note['target'] == 'after': + after_note = getSingleResult('select note_pos from notes_tree where note_id = ?', [note['target_note_id']]) + + new_note_pos = after_note['note_pos'] + 1 + + execute('update notes_tree set note_pos = note_pos + 1 where note_pid = ? and note_pos > ?', [parent_note_id, after_note['note_pos']]) + else: + raise Exception('Unknown target: ' + note['target']) + + now = math.floor(time.time()) + + insert("notes", { + 'note_id': noteId, + 'note_title': note['note_title'], + 'note_text': '', + 'note_clone_id': '', + 'date_created': now, + 'date_modified': now, + 'icon_info': 'pencil', + 'is_finished': 0 + }) + + insert("notes_tree", { + 'note_id': noteId, + 'note_pid': parent_note_id, + 'note_pos': new_note_pos, + 'is_expanded': 0 + }) + + commit() + + return jsonify({ + 'note_id': noteId + }) + +@notes_api.route('/notes', methods = ['GET']) +@login_required +def searchNotes(): + search = '%' + request.args['search'] + '%' + + result = getResults("select note_id from notes where note_title like ? or note_text like ?", [search, search]) + + noteIdList = [] + + for res in result: + noteIdList.append(res['note_id']) + + return jsonify(noteIdList) \ No newline at end of file diff --git a/src/notes_children.py b/src/notes_children.py deleted file mode 100644 index f3f790890..000000000 --- a/src/notes_children.py +++ /dev/null @@ -1,64 +0,0 @@ -import math -import random -import string -import time - -from flask import request -from flask_restful import Resource - -from sql import execute, insert, getSingleResult, commit - - -class NotesChildren(Resource): - def post(self, parent_note_id): - note = request.get_json(force=True) - - noteId = ''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(22)) - - if parent_note_id == "root": - parent_note_id = "" - - new_note_pos = 0 - - if note['target'] == 'into': - res = getSingleResult('select max(note_pos) as max_note_pos from notes_tree where note_pid = ?', [parent_note_id]) - max_note_pos = res['max_note_pos'] - - if max_note_pos is None: # no children yet - new_note_pos = 0 - else: - new_note_pos = max_note_pos + 1 - elif note['target'] == 'after': - after_note = getSingleResult('select note_pos from notes_tree where note_id = ?', [note['target_note_id']]) - - new_note_pos = after_note['note_pos'] + 1 - - execute('update notes_tree set note_pos = note_pos + 1 where note_pid = ? and note_pos > ?', [parent_note_id, after_note['note_pos']]) - else: - raise Exception('Unknown target: ' + note['target']) - - now = math.floor(time.time()) - - insert("notes", { - 'note_id': noteId, - 'note_title': note['note_title'], - 'note_text': '', - 'note_clone_id': '', - 'date_created': now, - 'date_modified': now, - 'icon_info': 'pencil', - 'is_finished': 0 - }) - - insert("notes_tree", { - 'note_id': noteId, - 'note_pid': parent_note_id, - 'note_pos': new_note_pos, - 'is_expanded': 0 - }) - - commit() - - return { - 'note_id': noteId - } diff --git a/src/notes_move_api.py b/src/notes_move_api.py new file mode 100644 index 000000000..d8489c94e --- /dev/null +++ b/src/notes_move_api.py @@ -0,0 +1,57 @@ +from flask import Blueprint, jsonify +from flask_login import login_required + +from sql import execute, commit +from sql import getSingleResult + +notes_move_api = Blueprint('notes_move_api', __name__) + +@notes_move_api.route('/notes//moveTo/', methods = ['PUT']) +@login_required +def moveToNote(note_id, parent_id): + res = getSingleResult('select max(note_pos) as max_note_pos from notes_tree where note_pid = ?', [parent_id]) + max_note_pos = res['max_note_pos'] + new_note_pos = 0 + + if max_note_pos is None: # no children yet + new_note_pos = 0 + else: + new_note_pos = max_note_pos + 1 + + execute("update notes_tree set note_pid = ?, note_pos = ? where note_id = ?", [parent_id, new_note_pos, note_id]) + + commit() + return jsonify({}) + +@notes_move_api.route('/notes//moveBefore/', methods = ['PUT']) +def moveBeforeNote(note_id, before_note_id): + before_note = getSingleResult("select * from notes_tree where note_id = ?", [before_note_id]) + + if before_note <> None: + execute("update notes_tree set note_pos = note_pos + 1 where note_id = ?", [before_note_id]) + + execute("update notes_tree set note_pid = ?, note_pos = ? where note_id = ?", [before_note['note_pid'], before_note['note_pos'], note_id]) + + commit() + + return jsonify({}) + +@notes_move_api.route('/notes//moveAfter/', methods = ['PUT']) +def moveAfterNote(note_id, after_note_id): + after_note = getSingleResult("select * from notes_tree where note_id = ?", [after_note_id]) + + if after_note <> None: + execute("update notes_tree set note_pos = note_pos + 1 where note_pid = ? and note_pos > ?", [after_note['note_pid'], after_note['note_pos']]) + + execute("update notes_tree set note_pid = ?, note_pos = ? where note_id = ?", [after_note['note_pid'], after_note['note_pos'] + 1, note_id]) + + commit() + + return jsonify({}) + +@notes_move_api.route('/notes//expanded/', methods = ['PUT']) +def setExpandedNote(note_id, expanded): + execute("update notes_tree set is_expanded = ? where note_id = ?", [expanded, note_id]) + + commit() + return jsonify({}) \ No newline at end of file diff --git a/src/notes_search.py b/src/notes_search.py deleted file mode 100644 index 2a3511003..000000000 --- a/src/notes_search.py +++ /dev/null @@ -1,18 +0,0 @@ -from flask import request -from flask_restful import Resource - -from sql import getResults - - -class NotesSearch(Resource): - def get(self): - search = '%' + request.args['search'] + '%' - - result = getResults("select note_id from notes where note_title like ? or note_text like ?", [search, search]) - - noteIdList = []; - - for res in result: - noteIdList.append(res['note_id']) - - return noteIdList \ No newline at end of file diff --git a/src/tree.py b/src/tree.py deleted file mode 100644 index e16618083..000000000 --- a/src/tree.py +++ /dev/null @@ -1,40 +0,0 @@ -from flask_restful import Resource - -from sql import getResults, getSingleResult - - -class Tree(Resource): - def get(self): - notes = getResults("select " - "notes_tree.*, " - "COALESCE(clone.note_title, notes.note_title) as note_title, " - "notes.note_clone_id, " - "case when notes.note_clone_id is null or notes.note_clone_id = '' then 0 else 1 end as is_clone " - "from notes_tree " - "join notes on notes.note_id = notes_tree.note_id " - "left join notes as clone on notes.note_clone_id = clone.note_id " - "order by note_pid, note_pos") - - rootNotes = [] - notesMap = {} - - for note in notes: - note['children'] = [] - - if not note['note_pid']: - rootNotes.append(note) - - notesMap[note['note_id']] = note - - for note in notes: - if note['note_pid'] != "": - parent = notesMap[note['note_pid']] - - parent['children'].append(note) - parent['folder'] = True - - retObject = {} - retObject['notes'] = rootNotes - retObject['start_note_id'] = getSingleResult('select * from options where opt_name = "start_node"')['opt_value']; - - return retObject diff --git a/src/tree_api.py b/src/tree_api.py new file mode 100644 index 000000000..b260812e5 --- /dev/null +++ b/src/tree_api.py @@ -0,0 +1,43 @@ +from flask import Blueprint, jsonify +from flask_login import login_required + +from sql import getResults, getSingleResult + +tree_api = Blueprint('tree_api', __name__) + +@tree_api.route('/tree', methods = ['GET']) +@login_required +def getTree(): + notes = getResults("select " + "notes_tree.*, " + "COALESCE(clone.note_title, notes.note_title) as note_title, " + "notes.note_clone_id, " + "case when notes.note_clone_id is null or notes.note_clone_id = '' then 0 else 1 end as is_clone " + "from notes_tree " + "join notes on notes.note_id = notes_tree.note_id " + "left join notes as clone on notes.note_clone_id = clone.note_id " + "order by note_pid, note_pos") + + rootNotes = [] + notesMap = {} + + for note in notes: + note['children'] = [] + + if not note['note_pid']: + rootNotes.append(note) + + notesMap[note['note_id']] = note + + for note in notes: + if note['note_pid'] != "": + parent = notesMap[note['note_pid']] + + parent['children'].append(note) + parent['folder'] = True + + retObject = {} + retObject['notes'] = rootNotes + retObject['start_note_id'] = getSingleResult('select * from options where opt_name = "start_node"')['opt_value']; + + return jsonify(retObject) \ No newline at end of file