Skip to content
16 changes: 7 additions & 9 deletions markovbot.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@

import asyncio
import gc
import os
import time

Expand All @@ -17,23 +16,22 @@
# filename='logs/discord.log', encoding='utf-8', mode='w')


def try_load_model() -> markovify.NewlineText:
async def try_load_model() -> markovify.NewlineText:
if not os.path.exists("data/markov_model.json"):
logger.info(
"markov_model.json not found. Loading messages.txt and creating model...")
text_model: markovify.NewlineText = model_manager.build_markov_model()
text_model: markovify.NewlineText = await model_manager.build_markov_model()
logger.info("Saving model to markov_model.json...")
model_manager.save_model(botconfig.STATE_SIZE)
await model_manager.save_model(botconfig.STATE_SIZE)
return text_model
else:
logger.info("markov_model.json found. Loading model...")
return model_manager.load_model()
return await model_manager.load_model()


load_time_s = time.time()
text_model: markovify.NewlineText = try_load_model()
load_time_s: float = time.time()
text_model: markovify.NewlineText = asyncio.run(try_load_model())
text_model.compile(inplace=True) # Compile the model for faster generation
load_time_e = time.time()
load_time_e: float = time.time()
logger.info(
f"Model loaded in {load_time_e - load_time_s:.4f} seconds.")

Expand Down
62 changes: 38 additions & 24 deletions model_manager.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,45 @@
import os

from aiofile import async_open
import markovify
from loguru import logger

import botconfig


def save_model(state_size: int) -> None:
with open("data/messages.txt", encoding="utf-8") as f:
text: str = f.read()
async def save_model(state_size: int) -> None:
async with async_open("data/messages.txt", "r", encoding="utf-8") as f:
text: str = await f.read()

text_model = markovify.NewlineText(
text, well_formed=False, state_size=state_size)
text_model.compile(inplace=True)
model_json: str = text_model.to_json()
try:
with open("data/markov_model.json", "w", encoding="utf-8") as model_file:
model_file.write(model_json)
except PermissionError as e:
logger.error(
f"Permission error while trying to save the model: {repr(e)}")
logger.info(
f"Permission is {os.access('data/markov_model.json', os.W_OK)}")


def load_model() -> markovify.NewlineText:
text, well_formed=False, state_size=state_size, retain_original=False)

del text

text_model.compile(inplace=True)
model_json: str = text_model.to_json()
try:
async with async_open("data/markov_model.json", "w", encoding="utf-8") as af:
await af.write(model_json)
del model_json
except PermissionError as e:
logger.error(
f"Permission error while trying to save the model: {repr(e)}")
logger.info(
f"Permission is {os.access('data/markov_model.json', os.W_OK)}")
return


async def load_model() -> markovify.NewlineText:
try:
with open("data/markov_model.json", "r", encoding="utf-8") as model_file:
model_json: str = model_file.read()
return markovify.NewlineText.from_json(model_json)
async with async_open("data/markov_model.json", "r", encoding="utf-8") as model_file:
logger.info("Reading markov_model file...")
model_json: str = await model_file.read()
logger.info("Loading model from_json...")
model = markovify.NewlineText.from_json(model_json)
logger.info("Deleting model_json from memory...")
del model_json
return model
except FileNotFoundError:
logger.error(
"markov_model.json not found. Please build the model first.")
Expand All @@ -41,11 +52,11 @@ def load_model() -> markovify.NewlineText:
raise


def build_markov_model() -> markovify.NewlineText:
async def build_markov_model() -> markovify.NewlineText:
logger.info("Loading messages.txt...")
try:
with open("data/messages.txt", "r", encoding="utf-8") as f:
text: str = f.read()
async with async_open("data/messages.txt", "r", encoding="utf-8") as af:
text: str = await af.read()
except FileNotFoundError:
logger.error(
"messages.txt not found. Please run the dataset generation script first.")
Expand All @@ -58,4 +69,7 @@ def build_markov_model() -> markovify.NewlineText:
raise

logger.info("Creating NewlineText. This may take a while")
return markovify.NewlineText(text, well_formed=False, state_size=botconfig.STATE_SIZE)
model = markovify.NewlineText(
text, well_formed=False, state_size=botconfig.STATE_SIZE)
del text
return model
5 changes: 3 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ description = "Markovbot is a Discord Bot that utilizes Markovify and Markov Cha
readme = "README.md"
requires-python = ">=3.14"
dependencies = [
"aiofile>=3.9.0",
"discord-py>=2.7.1",
"loguru>=0.7.3",
"markovify",
"tqdm>=4.67.3",
]

[tool.uv.sources]
markovify = { git = "https://github.com/bscout9956/markovify", branch = "orjson" }
markovify = { git = "https://github.com/bscout9956/markovify" }

[dependency-groups]
dev = ["snakeviz>=2.2.2"]
dev = ["pympler>=1.1", "snakeviz>=2.2.2"]
61 changes: 57 additions & 4 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading