On demand import functionality, held together with ductape and bubblegum.

This commit is contained in:
th3r00t
2020-09-02 17:42:08 -04:00
parent 938ef39821
commit 85fa88dcb0
6 changed files with 91 additions and 99 deletions

View File

@@ -4,7 +4,6 @@ import sys
from pathlib import Path from pathlib import Path
import websockets import websockets
from loguru import logger
from src.backend.lib.config import Config from src.backend.lib.config import Config
from src.backend.pyShelf_MakeCollections import MakeCollections from src.backend.pyShelf_MakeCollections import MakeCollections
@@ -26,6 +25,7 @@ async def runImport():
async def socketio(websocket, path): async def socketio(websocket, path):
async for message in websocket: async for message in websocket:
config.logger.info("Message Processing")
if message == "ping": if message == "ping":
config.logger.info("<< Ping") config.logger.info("<< Ping")
tx = pong(message) tx = pong(message)

View File

@@ -23,3 +23,4 @@ jsonpickle
django-widget-tweaks django-widget-tweaks
loguru loguru
ptvsd ptvsd
pudb

View File

@@ -19,7 +19,8 @@ class Config:
self._fp = "config.json" self._fp = "config.json"
self._cp = pathlib.Path.joinpath(root, self._fp) self._cp = pathlib.Path.joinpath(root, self._fp)
self._data = self.open_file() self._data = self.open_file()
self.logger = self.get_logger() try: self.logger
except AttributeError: self.logger = self.get_logger()
self.book_path = self._data["BOOKPATH"] self.book_path = self._data["BOOKPATH"]
self.TITLE = self._data["TITLE"] self.TITLE = self._data["TITLE"]
self.VERSION = self._data["VERSION"] self.VERSION = self._data["VERSION"]
@@ -30,11 +31,8 @@ class Config:
self.password = self._data["PASSWORD"] self.password = self._data["PASSWORD"]
self.db_host = self._data["DB_HOST"] self.db_host = self._data["DB_HOST"]
self.db_port = self._data["DB_PORT"] self.db_port = self._data["DB_PORT"]
self.file_array = [ self.file_array = [self.book_shelf]
self.book_shelf,
]
self.auto_scan = True self.auto_scan = True
self.allowed_hosts = self._data["ALLOWED_HOSTS"] self.allowed_hosts = self._data["ALLOWED_HOSTS"]
self.db_user = self._data["USER"] self.db_user = self._data["USER"]
self.db_pass = self._data["PASSWORD"] self.db_pass = self._data["PASSWORD"]
@@ -42,8 +40,8 @@ class Config:
def get_logger(self): def get_logger(self):
_logger = logger _logger = logger
_logger.add(pathlib.PurePath(self.root, 'data','pyShelf_{time}.log'), _logger.add(pathlib.PurePath(self.root, 'data','{time}.log'),
rotation="10 MB", enqueue=True, colorize=True) rotation="2 MB", enqueue=True, colorize=True)
return _logger return _logger
def open_file(self): def open_file(self):

View File

@@ -36,15 +36,22 @@ class Server:
:TODO: Document this :TODO: Document this
""" """
async def __init__(self, root): def __init__(self, root):
self.root = root self.root = root
self.host = ("127.0.0.1", 1337)
self.config = Config(self.root) self.config = Config(self.root)
self.instance = None self.loop = None
self.serve = await websockets.serve(socketio, "127.0.0.1", 1337) self.serve = None
async def __aexit__(self, *args, **kwargs): async def __aexit__(self, *args, **kwargs):
await self.serve.__aexit__(*args, **kwargs) await self.serve.__aexit__(*args, **kwargs)
async def initialize_server(self):
self.config.logger.info("INITIALIZE")
self.serve = await websockets.serve(self.socketio, self.host[0], self.host[1])
await asyncio.sleep(.01)
self.config.logger.info("Server Initialization Complete")
async def runImport(self): async def runImport(self):
_start_time = time.time() _start_time = time.time()
InitFiles(self.config.file_array) InitFiles(self.config.file_array)
@@ -55,21 +62,29 @@ class Server:
_total_time = round(time.time() - _start_time) _total_time = round(time.time() - _start_time)
async def socketio(self, websocket, path): async def socketio(self, websocket, path):
self.config.logger.info("Listener Starting")
async for message in websocket: async for message in websocket:
if message == "ping": if message == "ping":
config.logger.info("<< Ping") self.config.logger.info("<< Ping")
tx = self.pong() tx = self.pong()
elif message == "importBooks": elif message == "importBooks":
config.logger.info("Starting Import") self.config.logger.info("Starting Import")
tx = "Starting Import . . ." tx = "Starting Import . . ."
await websocket.send(tx) await websocket.send(tx)
await runImport() await asyncio.sleep(0.01)
await self.runImport()
await asyncio.sleep(0.01)
tx = "complete" tx = "complete"
else:
self.config.logger.info("Unhandled Message Rcvd :: {}".format(message))
await websocket.send(tx) await websocket.send(tx)
def pong(self): def pong(self):
self.config.logger.info(">> Pong") self.config.logger.info(">> Pong")
return "pong" return "pong"
def start(self): async def start(self):
asyncio.get_event_loop().run_until_complete(self.serve) self.loop = asyncio.get_running_loop()
self.loop.set_debug(True)
await websockets.serve(self.socketio, self.host[0], self.host[1])
await asyncio.sleep(1)

View File

@@ -1,3 +1,13 @@
async function WebSocketInterface(host) {
let socket = new WebSocket(host)
socket.onopen = function(e) { console.log('Connected') }
socket.onmessage = function (rcvd){
rx_msg(rcvd.data)
}}
async function rx_msg(rcvd) { console.log('msg :: '+rcvd) }
async function tx_msg(socket, msg) { socket.send(msg) }
$(document).ready(function(){ $(document).ready(function(){
function customlog(outstream) { function customlog(outstream) {
/* Gather my variables and output them */ /* Gather my variables and output them */
@@ -171,16 +181,9 @@ $(document).ready(function(){
$('#pop_over_0').dialog("open"); $('#pop_over_0').dialog("open");
}); });
$(document).on('click', '.logout-btn', function(){window.location.href = '/logout'}); $(document).on('click', '.logout-btn', function(){window.location.href = '/logout'});
//Web Socket Call
$(document).on('click', '.import-btn', async function(){ $(document).on('click', '.import-btn', async function(){
$.ajax({
type: "GET", url: "/live", data: {hook: 'import_books'},
success: function (response) {
},
error: function (response) {
customlog(["Failure", response]);
}
});
let connection = await ImportBooks(server);
popover.html('<div id="psout" class="container">'); popover.html('<div id="psout" class="container">');
let psout = $('#psout') let psout = $('#psout')
psout.append('<div class="rox"><div class="col import_status">Importing Books</div></div>') psout.append('<div class="rox"><div class="col import_status">Importing Books</div></div>')
@@ -192,6 +195,16 @@ $(document).ready(function(){
value: false value: false
}); });
$(".progressbar").append("</div>") $(".progressbar").append("</div>")
$.ajax({
type: "GET", url: "/live", data: {hook: 'import_books'},
success: async function (response,sock) {
customlog(["Backend Reports websocket server READY"])
$('.progressbar').progressbar({ value: true })
},
error: function (response) {
customlog(["Failure", response.data]);
}
});
}); });
$('#coll_button').on('click', function(){ $('#coll_button').on('click', function(){
var isopen = $('#pop_over_0').dialog("isOpen"); var isopen = $('#pop_over_0').dialog("isOpen");
@@ -285,59 +298,3 @@ function resize_search(win_width){
$('.search_string').val("Search"); $('.search_string').val("Search");
} }
} }
function OpenSocket(address) {
return new Promise(resolve => {
const connection = new WebSocket(address);
connection.onopen = function(e){
console.log('--[ Connection Established ]')
ping(connection)
};
connection.onmessage = function(rcvd){
sock_rx(rcvd)
};
resolve(connection);
});
}
function ImportBooks(address) {
return new Promise(resolve => {
const connection = new WebSocket(address);
connection.onopen = function(e){
sock_tx(connection,'importBooks')
};
connection.onmessage = function(rcvd){
sock_rx(rcvd)
};
resolve(connection);
});
}
async function PyshelfServer(address){
console.log("--[ Starting Connection ]")
return await OpenSocket(address)
}
function sock_rx(rcvd) {
if (rcvd.data == 'pong') { pong(rcvd) }
else if (rcvd.data == 'complete') {
$('.progressbar').progressbar("option", "value", "True");
$('.import_status').html('Import Complete')
console.log(rcvd.data)
}
else { console.log("<<[rx] :"+rcvd.data) }
}
function sock_tx(connection, msg) {
connection.send(msg);
}
function sock_status(connection) {
let buffered = connection.bufferedAmmount;
let ready = connection.readyState;
return [buffered, ready];
}
function ping(connection) {
connection.send('ping');
console.log("[ping]>>");
}
function pong(rcvd) {
console.log("<<["+rcvd+"]")
}

View File

@@ -7,6 +7,7 @@ import time
from base64 import b64decode, b64encode from base64 import b64decode, b64encode
from pathlib import Path from pathlib import Path
import websockets
from backend.lib.config import Config from backend.lib.config import Config
from backend.lib.pyShelf import Server from backend.lib.pyShelf import Server
from django.conf import settings from django.conf import settings
@@ -384,7 +385,7 @@ def collections_list():
return list(set(collection_key)) return list(set(collection_key))
def live(request, **kwargs): async def live(request, **kwargs):
""" """
Respond to live requests. Primarily used as a response object for Ajax calls Respond to live requests. Primarily used as a response object for Ajax calls
:param GET['hook']: collection_listing, book_details, register :param GET['hook']: collection_listing, book_details, register
@@ -411,33 +412,53 @@ def live(request, **kwargs):
return JsonResponse({"data": html}) return JsonResponse({"data": html})
elif hook == "import_books": elif hook == "import_books":
"""TODO: Spawn websocket server""" _test_count = 0
breakpoint() await Server(Path.absolute(Path.cwd().parent)).start()
################################################### await asyncio.sleep(1)
# async def responder(socket): #
# await catalogue.import_books(socket=socket) # async def test_connection(host, counter):
# return JsonResponse({"data": None}) # async with websockets.connect(f'ws://{host[0]}:{host[1]}') as _s:
# pass # await _s.send("ping")
# asyncio.run(responder(None)) # data = await _s.recv()
################################################### counter = counter + 1
def test_connection(host): if data == "pong":
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: return True
s.connect(host) else:
s.sendall(b"ping") return False
data = s.recv(1024)
return data async def runImport(host):
async with websockets.connect(f'ws://{host[0]}:{host[1]}') as _s:
await _s.send("importBooks")
data = await _s.recv()
if data == "complete":
return JsonResponse({"data": data})
else:
return False
_host = ("127.0.0.1", 1337) _host = ("127.0.0.1", 1337)
_test_count = 0
try: try:
_server_response = test_connection(_host) if await test_connection(_host, _test_count):
config.logger.info("Connection Successful")
await runImport(_host)
return JsonResponse({"data": "Response sent"}, status=200)
except ConnectionRefusedError as e: except ConnectionRefusedError as e:
config.logger.info(e) config.logger.info(e)
if e.errno == 111: if e.errno == 111:
request.server = Server(Path.absolute(Path.cwd().parent)).start() await Server(Path.absolute(Path.cwd().parent)).start()
if await test_connection(_host, _test_count):
return JsonResponse({"data": "Response sent"}, status=200)
elif not await test_connection(_host, _test_count) & _test_count >=4:
await Server(Path.absolute(Path.cwd().parent)).start()
await test_connection(_host, _test_count)
else:
return JsonResponse({"data": "Websocket Failed Testing"}, status=401)
else: return JsonResponse(err_txt, status=404) else: return JsonResponse(err_txt, status=404)
return JsonResponse({"data": "Response sent"}, status=200) return JsonResponse({"data": "Response sent"}, status=200)
def book_details(book): def book_details(book):
return { return {
'title': book.title, 'title': book.title,