Searching complete?

This commit is contained in:
Carlos Sanchez 2023-05-01 11:21:45 -04:00
parent e0393cf410
commit 5240b434a3
4 changed files with 63 additions and 14 deletions

View File

@ -104,10 +104,11 @@ class ApiContext:
def api_status(self): def api_status(self):
return self.get("status") return self.get("status")
# Access the raw search endpoint of the API (you must construct the special contentapi request yourself!)
def search(self, requests): def search(self, requests):
return self.post("request", requests) return self.post("request", requests)
# A very basic search for outputting to the console. Many assumptions are made! # A very basic search for outputting to the console. Constructs the contentapi search request for you: many assumptions are made!
def basic_search(self, searchterm, limit = 0): def basic_search(self, searchterm, limit = 0):
return self.search({ return self.search({
"values": { "values": {

48
main.py
View File

@ -9,6 +9,7 @@ import re
import toml import toml
import readchar import readchar
import websocket import websocket
import win_unicode_console
from collections import OrderedDict from collections import OrderedDict
from colorama import Fore, Back, Style, init as colorama_init from colorama import Fore, Back, Style, init as colorama_init
@ -17,6 +18,7 @@ import contentapi
import myutils import myutils
CONFIGFILE="config.toml" CONFIGFILE="config.toml"
MAXTITLE=25
# The entire config object with all defaults # The entire config object with all defaults
config = { config = {
@ -42,6 +44,7 @@ commands = OrderedDict([
def main(): def main():
print("Program start") print("Program start")
win_unicode_console.enable()
colorama_init() # colorama init colorama_init() # colorama init
load_or_create_global_config() load_or_create_global_config()
@ -66,12 +69,22 @@ def main():
ws = websocket.WebSocketApp(context.websocket_endpoint()) ws = websocket.WebSocketApp(context.websocket_endpoint())
# Might as well reuse the websocket object for my websocket context data (oops, is that bad?) # Might as well reuse the websocket object for my websocket context data (oops, is that bad?)
ws.context = context
ws.user_info = context.user_me() ws.user_info = context.user_me()
ws.current_room = config["default_room"]
ws.current_room_data = False
ws.pause_output = False # Whether all output from the websocket should be paused (including status updates) ws.pause_output = False # Whether all output from the websocket should be paused (including status updates)
ws.output_buffer = [] # Individual print statements buffered from output. ws.output_buffer = [] # Individual print statements buffered from output.
ws.main_config = config ws.main_config = config
ws.current_room = 0
ws.current_room_data = False
# Go out and get the default room if one was provided.
if config["default_room"]:
try:
ws.current_room_data = context.get_by_id("content", config["default_room"])
ws.current_room = config["default_room"]
printr(Fore.GREEN + "Found default room %s" % ws.current_room_data["name"])
except Exception as ex:
printr(Fore.YELLOW + "Error searching for default room %d: %s" % (config["default_room"], ex))
# set the callback functions # set the callback functions
ws.on_open = ws_onopen ws.on_open = ws_onopen
@ -93,11 +106,10 @@ def ws_onopen(ws):
def main_loop(): def main_loop():
printstatus = True printstatus = True
print(Fore.GREEN + Style.BRIGHT + "\n-- Connected to live updates! --" + Style.RESET_ALL) printr(Fore.GREEN + Style.BRIGHT + "\n-- Connected to live updates! --")
# TODO: check to see if the id is a valid room
if not ws.current_room: if not ws.current_room:
print(Fore.YELLOW + "* You are not connected to any room! Press 'S' to search for a room! *" + Style.RESET_ALL) printr(Fore.YELLOW + "* You are not connected to any room! Press 'S' to search for a room! *")
# The infinite input loop! Or something! # The infinite input loop! Or something!
while True: while True:
@ -176,10 +188,22 @@ def search(ws):
return return
match = re.match(r'#(\d+)', searchterm) match = re.match(r'#(\d+)', searchterm)
if match: if match:
digits = int(match.group(1)) roomid = int(match.group(1))
try:
num = int(digits) ws.current_room_data = ws.context.get_by_id("content", roomid)
print(num) ws.current_room = roomid
print(Fore.GREEN + "Set room to %s" % ws.current_room_data["name"] + Style.RESET_ALL)
return
except Exception as ex:
print(Fore.RED + "Couldn't find room with id %d" % roomid + Style.RESET_ALL)
elif searchterm:
# Go search for rooms and display them
result = ws.context.basic_search(searchterm)["objects"]["content"]
if len(result):
for content in result:
printr(Style.BRIGHT + "%7s" % ("#%d" % content["id"]) + Style.RESET_ALL + " - %s" % content["name"])
else:
printr(Style.DIM + " -- No results -- ")
# Either pull the token from a file, or get the login from the command # Either pull the token from a file, or get the login from the command
# line if that doesn't work. WILL test your token against the real API # line if that doesn't work. WILL test your token against the real API
@ -218,11 +242,15 @@ def print_statusline(ws):
# if ws_context.connected: bg = Back.GREEN else: bg = Back.RED # if ws_context.connected: bg = Back.GREEN else: bg = Back.RED
if ws.current_room: if ws.current_room:
name = ws.current_room_data["name"] name = ws.current_room_data["name"]
room = "'" + (name[:12] + '...' if len(name) > 15 else name) + "'" room = "'" + (name[:(MAXTITLE - 3)] + '...' if len(name) > MAXTITLE else name) + "'"
else: else:
room = Fore.RED + Style.DIM + "NONE" + Style.NORMAL + Fore.BLACK room = Fore.RED + Style.DIM + "NONE" + Style.NORMAL + Fore.BLACK
print(Back.GREEN + Fore.BLACK + "\n " + ws.user_info["username"] + " - " + room + " CTRL: h s g u i q " + Style.RESET_ALL) print(Back.GREEN + Fore.BLACK + "\n " + ws.user_info["username"] + " - " + room + " CTRL: h s g u i q " + Style.RESET_ALL)
# Print and then reset the style
def printr(msg):
print(msg + Style.RESET_ALL)
# Because python reasons # Because python reasons
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@ -4,7 +4,7 @@ REM Change python whatever
set pyexe=python34\python.exe set pyexe=python34\python.exe
REM The list of packages this thing requires (maybe?) REM The list of packages this thing requires (maybe?)
set packages=requests colorama==0.4.1 websocket-client toml readchar set packages=requests colorama==0.4.1 websocket-client toml readchar win-unicode-console
REM Actually install the packages... maybe? REM Actually install the packages... maybe?
%pyexe% -m pip install %packages% %pyexe% -m pip install %packages%

View File

@ -6,12 +6,14 @@ import logging
class TestContentapi(unittest.TestCase): class TestContentapi(unittest.TestCase):
def setUp(self) -> None: def setUp(self) -> None:
# MAYBE change this some time? # MAYBE change all these some time? Should connect to a local instance!!
self.api = contentapi.ApiContext("https://oboy.smilebasicsource.com/api", logging) self.api = contentapi.ApiContext("https://oboy.smilebasicsource.com/api", logging)
self.known_content_id = 384
self.known_name = "Megathread"
def test_apistatus(self): def test_apistatus(self):
result = self.api.api_status() result = self.api.api_status()
self.assertTrue("version" in result) self.assertIn("version", result)
def test_is_token_valid_none(self): def test_is_token_valid_none(self):
self.assertFalse(self.api.is_token_valid()) self.assertFalse(self.api.is_token_valid())
@ -19,7 +21,25 @@ class TestContentapi(unittest.TestCase):
def test_is_token_valid_garbage(self): def test_is_token_valid_garbage(self):
self.api.token = "literalgarbage" self.api.token = "literalgarbage"
self.assertFalse(self.api.is_token_valid()) self.assertFalse(self.api.is_token_valid())
def test_get_by_id_notfound(self):
try:
self.api.get_by_id("content", 0)
except contentapi.NotFoundError:
return
self.assertFalse(True, "Didn't throw expected exception!")
def test_get_by_id_known(self):
result = self.api.get_by_id("content", self.known_content_id)
self.assertIn("id", result)
self.assertEqual(result["id"], self.known_content_id)
def test_basic_search(self):
result = self.api.basic_search(self.known_name)
self.assertIn("content", result["objects"])
self.assertTrue(len(result["objects"]["content"]) >= 1)
self.assertTrue(any(self.known_name in item["name"] for item in result["objects"]["content"]))
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()