diff --git a/myapp/__init__.py b/myapp/__init__.py index 47490b9..1380439 100644 --- a/myapp/__init__.py +++ b/myapp/__init__.py @@ -8,6 +8,7 @@ import logging from flask import Flask from logging.handlers import RotatingFileHandler + app = Flask(__name__) app.config.from_object(config.CONFIG) diff --git a/myapp/api/__init__.py b/myapp/api/__init__.py new file mode 100644 index 0000000..d5d2007 --- /dev/null +++ b/myapp/api/__init__.py @@ -0,0 +1,12 @@ +__author__ = 'RemiZOffAlex' +__copyright__ = '(c) RemiZOffAlex' +__email__ = 'remizoffalex@mail.ru' + +from jsonrpc import JSONRPC + + +jsonrpc = JSONRPC() + +from . import ( # noqa F401 + user +) diff --git a/myapp/api/user.py b/myapp/api/user.py new file mode 100644 index 0000000..6ce5558 --- /dev/null +++ b/myapp/api/user.py @@ -0,0 +1,151 @@ +__author__ = 'RemiZOffAlex' +__copyright__ = '(c) RemiZOffAlex' +__email__ = 'remizoffalex@mail.ru' + +from . import jsonrpc +from .. import app, lib, models + + +@jsonrpc.method('user.add') +def user_add(username: str, password: str) -> dict: + """Новый пользователь + """ + if username is None or len(username) < 4 or len(username) > 25: + raise ValueError('Длина логина должна быть от 4 до 25 символов') + if password is None or len(password) < 4 or len(password) > 25: + raise ValueError('Длина пароля должна быть от 4 до 25 символов') + user = models.db_session.query( + models.User + ).filter( + models.User.name == username + ).first() + if user: + raise ValueError('Пользователь с таким логином уже существует') + + newuser = models.User( + username + ) + newuser.password = lib.get_hash_password( + password, + app.config['SECRET_KEY'] + ) + models.db_session.add(newuser) + models.db_session.commit() + + result = newuser.as_dict() + return result + + +@jsonrpc.method('user.enable') +def user_enable(id: int) -> dict: + """Разблокировать пользователя + """ + userRow = models.db_session.query( + models.User + ).filter( + models.User.id == id + ).first() + if userRow is None: + raise ValueError + userRow.disable = False + models.db_session.commit() + return userRow.as_dict() + + +@jsonrpc.method('user.pages') +def user_pages_list(id: int, page: int) -> list: + """Список статей пользователя + """ + user = models.db_session.query( + models.User + ).filter( + models.User.id == id + ).first() + if user is None: + raise ValueError + pages = models.db_session.query( + models.Page + ).filter( + models.Page.user_id == id + ).order_by( + models.Page.title.asc() + ) + pages = lib.getpage( + pages, + page, + app.config['ITEMS_ON_PAGE'] + ).all() + + result = [] + for page in pages: + newRow = page.as_dict() + newRow['user'] = page.user.as_dict() + newRow['tags'] = [] + for tagLink in page.tags: + newRow['tags'].append(tagLink.tag.as_dict()) + result.append(newRow) + return result + + +@jsonrpc.method('user.pages.count') +def user_pages_count(id: int) -> int: + """Общее количество статей + """ + user = models.db_session.query( + models.User + ).filter( + models.User.id == id + ).first() + if user is None: + raise ValueError + result = models.db_session.query( + models.Page + ).filter( + models.Page.user_id == id + ).count() + return result + + +@jsonrpc.method('users') +def users_list( + page: int = 1, + order_by: dict = {'field': 'name', 'order': 'asc'} +) -> list: + """Показать список пользователей + """ + users = models.db_session.query( + models.User + ) + + # Сортировка + if order_by['field'] not in ['name', 'created']: + raise ValueError + if order_by['order'] not in ['asc', 'desc']: + raise ValueError + field = getattr(models.User, order_by['field']) + order = getattr(field, order_by['order']) + users = users.order_by( + order() + ) + + users = lib.getpage( + users, + page, + app.config['ITEMS_ON_PAGE'] + ).all() + + result = [] + for item in users: + result.append(item.as_dict()) + return result + + +@jsonrpc.method('users.count') +def users_count() -> int: + """Количество список пользователей + """ + result = models.db_session.query( + models.User + ).count() + + return result diff --git a/myapp/bin/api.py b/myapp/bin/api.py new file mode 100755 index 0000000..9b36a75 --- /dev/null +++ b/myapp/bin/api.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 + +__author__ = 'RemiZOffAlex' +__copyright__ = '(c) RemiZOffAlex' +__email__ = 'remizoffalex@mail.ru' + +import sys +import json +import argparse +import traceback + +from .. import app +from ..api import jsonrpc + + +def main(): + parser = argparse.ArgumentParser( + description='API', + formatter_class=argparse.ArgumentDefaultsHelpFormatter + ) + parser._optionals.title = "Необязательные аргументы" + + parser.add_argument("--json-rpc", help="JSON-RPC") + parser.add_argument("--methods", action='store_true') + parser.add_argument("--example", action='store_true') + parser.add_argument("--verbose", action='store_true') + parser.add_argument("--save") + + args = parser.parse_args() + + if args.json_rpc: + request = json.loads(args.json_rpc) + if args.verbose: + app.logger.info(request) + result = jsonrpc(request) + if args.save: + with open(args.save, 'w') as fd: + fd.write(result) + print(result) + + if args.methods: + print(jsonrpc.methods) + print('[{0}]'.format(', '.join(jsonrpc.methods))) + + if args.example: + print(jsonrpc.example) + + +if __name__ == "__main__": + try: + main() + except Exception as err: + traceback.print_exc(file=sys.stdout) + exit(1) + + exit(0) diff --git a/myapp/models/users.py b/myapp/models/users.py index 4d03f8b..ba259d3 100644 --- a/myapp/models/users.py +++ b/myapp/models/users.py @@ -7,7 +7,6 @@ from sqlalchemy import ( Column, Boolean, Integer, - ForeignKey, String, DateTime ) diff --git a/myapp/ns_api/__init__.py b/myapp/ns_api/__init__.py index da717b3..4456257 100644 --- a/myapp/ns_api/__init__.py +++ b/myapp/ns_api/__init__.py @@ -3,7 +3,8 @@ __copyright__ = '(c) RemiZOffAlex' __email__ = 'remizoffalex@mail.ru' from functools import wraps -from flask_jsonrpc import JSONRPC +from jsonrpc import JSONRPC +from jsonrpc.backend.flask import APIView from flask import session from .. import app, models @@ -29,7 +30,7 @@ def login_required(func): return decorated_function -jsonrpc = JSONRPC(app, '/api') +jsonrpc = JSONRPC() from . import ( # noqa F401 login, @@ -38,3 +39,16 @@ from . import ( # noqa F401 tag, user ) + +app.add_url_rule('/api', view_func=APIView.as_view('api', jsonrpc=jsonrpc)) + + +@jsonrpc.method('api.methods') +def api_methods() -> dict: + """Список методов API + """ + + result = {} + for method in jsonrpc.methods: + result[method] = jsonrpc.description(method) + return result diff --git a/myapp/ns_api/login.py b/myapp/ns_api/login.py index db72454..36712a0 100644 --- a/myapp/ns_api/login.py +++ b/myapp/ns_api/login.py @@ -20,7 +20,7 @@ def login(username: str, password: str) -> bool: password, app.config['SECRET_KEY'] ), - models.User.disabled == False + models.User.disabled == False # noqa E712 ).first() if user is None: raise ValueError diff --git a/myapp/ns_api/page.py b/myapp/ns_api/page.py index ef7c19d..b279538 100644 --- a/myapp/ns_api/page.py +++ b/myapp/ns_api/page.py @@ -91,7 +91,10 @@ def page_update(id: int, title: str, text: str) -> dict: @jsonrpc.method('pages') -def pages_list(page: int, order_by: dict = {'field': 'title', 'order': 'asc'}) -> list: +def pages_list( + page: int = 1, + order_by: dict = {'field': 'title', 'order': 'asc'} +) -> list: """Список статей """ pages = models.db_session.query( diff --git a/myapp/ns_api/user.py b/myapp/ns_api/user.py index f65ecc1..6ce5558 100644 --- a/myapp/ns_api/user.py +++ b/myapp/ns_api/user.py @@ -107,7 +107,10 @@ def user_pages_count(id: int) -> int: @jsonrpc.method('users') -def users_list(page: int, order_by: dict = {'field': 'name', 'order': 'asc'}) -> list: +def users_list( + page: int = 1, + order_by: dict = {'field': 'name', 'order': 'asc'} +) -> list: """Показать список пользователей """ users = models.db_session.query( diff --git a/myapp/ns_login/templates/login.html b/myapp/ns_login/templates/login.html index e7a1496..89532af 100644 --- a/myapp/ns_login/templates/login.html +++ b/myapp/ns_login/templates/login.html @@ -40,38 +40,35 @@ {% block script %} {% endblock %} diff --git a/myapp/ns_note/templates/note.html b/myapp/ns_note/templates/note.html index 09588a3..58b1847 100644 --- a/myapp/ns_note/templates/note.html +++ b/myapp/ns_note/templates/note.html @@ -1,4 +1,4 @@ -{% extends "user/skeleton.html" %} +{% extends "private/skeleton.html" %} {% block content %} {% raw %} @@ -59,7 +59,7 @@ var app = new Vue({ } ); }, - showPanel: function(panel) { + panel_show: function(panel) { /* Показать/скрыть панель */ panel.visible = !panel.visible; }, diff --git a/myapp/ns_note/templates/note_add.html b/myapp/ns_note/templates/note_add.html index 4329e95..4fb3e06 100644 --- a/myapp/ns_note/templates/note_add.html +++ b/myapp/ns_note/templates/note_add.html @@ -1,4 +1,4 @@ -{% extends "user/skeleton.html" %} +{% extends "private/skeleton.html" %} {% block content %} diff --git a/myapp/ns_note/templates/note_edit.html b/myapp/ns_note/templates/note_edit.html index 388be28..3d39084 100644 --- a/myapp/ns_note/templates/note_edit.html +++ b/myapp/ns_note/templates/note_edit.html @@ -1,4 +1,4 @@ -{% extends "user/skeleton.html" %} +{% extends "private/skeleton.html" %} {% block content %}