Skip to content

Commit

Permalink
v0.14.0 - support save interactive data into database sqlite (#51)
Browse files Browse the repository at this point in the history
* support save interactive data

* support create table when init

* change file path

* remove wrong path of sqlite

* fix Nonetype error

* fix Nonetype error2
  • Loading branch information
yumiguan authored and zhaoye committed Nov 14, 2018
1 parent 82387bc commit c0520fc
Show file tree
Hide file tree
Showing 11 changed files with 96 additions and 24 deletions.
2 changes: 1 addition & 1 deletion lyrebird/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def subscribe(channel, func, *args, **kwargs):
:param sender: 信号发送者标识
"""
# context.application.event_bus.subscribe(channel, func)
application.server['event'].subscribe(channel, func)
application.server['event'].subscribe(channel, func, *args, **kwargs)


def publish(channel, event, *args, **kwargs):
Expand Down
3 changes: 2 additions & 1 deletion lyrebird/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,5 @@ def raw(self):


def root_dir():
return _cm.ROOT
if _cm:
return _cm.ROOT
36 changes: 23 additions & 13 deletions lyrebird/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,12 @@ def __init__(self):
self.any_channel = []
self.broadcast_executor = ThreadPoolExecutor(max_workers=10, thread_name_prefix='event-broadcast')

def broadcast_handler(self, callback_fn, message):
def broadcast_handler(self, callback_fn, event, args, kwargs):
try:
callback_fn(message)
if kwargs.get('event', False):
callback_fn(event)
else:
callback_fn(event.message)
except Exception:
# TODO handle exceptioins and send to event bus
traceback.print_exc()
Expand All @@ -47,10 +50,10 @@ def run(self):
e = self.event_queue.get()
callback_fn_list = self.pubsub_channels.get(e.channel)
if callback_fn_list:
for callback_fn in callback_fn_list:
self.broadcast_executor.submit(self.broadcast_handler, callback_fn, e.message)
for callback_fn in self.any_channel:
self.broadcast_executor.submit(self.broadcast_handler, callback_fn, e.message)
for callback_fn, args, kwargs in callback_fn_list:
self.broadcast_executor.submit(self.broadcast_handler, callback_fn, e, args, kwargs)
for callback_fn, args, kwargs in self.any_channel:
self.broadcast_executor.submit(self.broadcast_handler, callback_fn, e, args, kwargs)
except Exception:
# empty event
traceback.print_exc()
Expand All @@ -74,24 +77,31 @@ def subscribe(self, channel, callback_fn, *args, **kwargs):
"""
Subscribe channel with a callback function
That function will be called when a new message was published into it's channel
kwargs:
event=False receiver gets a message dict
event=True receiver gets an Event object
"""
if channel == 'any':
self.any_channel.append(callback_fn)
self.any_channel.append([callback_fn, args, kwargs])
else:
callback_fn_list = self.pubsub_channels.setdefault(channel, [])
callback_fn_list.append(callback_fn)
callback_fn_list.append([callback_fn, args, kwargs])


def unsubscribe(self, channel, callback_fn, *args, **kwargs):
def unsubscribe(self, channel, target_callback_fn, *args, **kwargs):
"""
Unsubscribe callback function from channel
"""
if channel == 'any' and callback_fn in self.any_channel:
self.any_channel.remove(callback_fn)
if channel == 'any':
for any_channel_fn, *_ in self.any_channel:
if target_callback_fn == any_channel_fn:
self.any_channel.remove([target_callback_fn, *_])
else:
callback_fn_list = self.pubsub_channels.get(channel)
if callback_fn_list and callback_fn in callback_fn_list:
callback_fn_list.remove(callback_fn)
for callback_fn, *_ in callback_fn_list:
if target_callback_fn == callback_fn:
callback_fn_list.remove([target_callback_fn, *_])


class CustomEventReceiver:
Expand Down
2 changes: 1 addition & 1 deletion lyrebird/mock/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def save(self):


application = Application()

db = None

def make_ok_response(**kwargs):
ok_resp = {
Expand Down
Empty file added lyrebird/mock/db/__init__.py
Empty file.
17 changes: 17 additions & 0 deletions lyrebird/mock/db/database.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from flask_sqlalchemy import SQLAlchemy

class DataBase:
def __init__(self, app):
self._db = SQLAlchemy(app)
self._db.init_app(app)

@property
def model(self):
return self._db.Model

@property
def session(self):
return self._db.session

def create_all(self):
self._db.create_all()
28 changes: 28 additions & 0 deletions lyrebird/mock/db/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import json
import datetime
import lyrebird
from lyrebird.mock import context
from sqlalchemy import Column, Table, String, Integer, DateTime, Text


class Flow(context.db.model):

id = Column(Integer, primary_key=True, autoincrement=True)
channel = Column(String(16))
content = Column(Text)
ts = Column(DateTime(timezone=True), default=datetime.datetime.now)

def __init__(self, channel, content):
self.channel = channel
self.content = content

def active_db_listener():
lyrebird.subscribe('any', save_data_into_db, event=True)
context.db.create_all()

def save_data_into_db(event):
message, channel = event.message, event.channel
content = json.dumps(message)
data = Flow(channel, content)
context.db.session.add(data)
context.db.session.commit()
9 changes: 5 additions & 4 deletions lyrebird/mock/handlers/mock_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ class MockHandler:
"""
def handle(self, handler_context):
data_group = context.application.data_manager.current_data_group
if data_group:
handler_context.response = data_group.get_response(handler_context.get_origin_url(),
handler_context.request.data)
pass
# data_group = context.application.data_manager.current_data_group
# if data_group:
# handler_context.response = data_group.get_response(handler_context.get_origin_url(),
# handler_context.request.data)
20 changes: 17 additions & 3 deletions lyrebird/mock/mock_server.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import json
import os
import sys
import socket
import json
import errno
import socket
import datetime
import subprocess
from . import plugin_manager
from flask import Flask, request, redirect, url_for, Response
Expand All @@ -14,10 +14,11 @@
from flask_socketio import SocketIO
from .reporter import report_handler
from ..version import VERSION
import datetime
from lyrebird.base_server import ThreadServer
from lyrebird import application
from lyrebird import log
from flask_sqlalchemy import SQLAlchemy
from lyrebird.mock.db.database import DataBase


"""
Expand Down Expand Up @@ -74,6 +75,16 @@ def __init__(self):
raise SyntaxError('Can not start mock server without config file.'
' Default config file path = api-mock/conf.json')

# sqlite初始化
ROOT_DIR = application.root_dir()
DB_FILE_NAME = 'lyrebird.db'
if ROOT_DIR:
SQLALCHEMY_DATABASE_URI = ROOT_DIR/DB_FILE_NAME
# TODO: 'sqlite:///' is unfriendly to windows
self.app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///'+str(SQLALCHEMY_DATABASE_URI)
self.app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
context.db = DataBase(self.app)

# 插件初始化
plugin_manager.load()
# 加载插件界面
Expand Down Expand Up @@ -105,6 +116,9 @@ def run(self):
server_ip = application.config.get('ip')
_logger.warning(f'start on http://{server_ip}:{self.port}')
report_handler.start()
# cannot import at beginning, cause db hasn't init
from lyrebird.mock.db.models import active_db_listener
active_db_listener()
self.socket_io.run(self.app, host='0.0.0.0', port=self.port, debug=True, use_reloader=False)


Expand Down
2 changes: 1 addition & 1 deletion lyrebird/version.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
IVERSION = (0, 13, 9)
IVERSION = (0, 14, 0)
VERSION = ".".join(str(i) for i in IVERSION)
LYREBIRD = "Lyrebird " + VERSION
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ requests==2.13.0
fire==0.1.0
flask-socketio
flask-restful
Flask-SQLAlchemy
beautifulsoup4
pytest
portpicker
Expand Down

0 comments on commit c0520fc

Please sign in to comment.