Move session log handling to a separate class, and use jsonl format

This commit is contained in:
Veronica Berglyd Olsen
2023-06-12 01:50:27 +02:00
parent aea41032ef
commit eba6783816
7 changed files with 199 additions and 72 deletions
+125
View File
@@ -0,0 +1,125 @@
"""
novelWriter Project Session Log Class
=======================================
File History:
Created: 2023-06-11 [2.1b1]
This file is a part of novelWriter
Copyright 20182023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
from __future__ import annotations
import json
import logging
from time import time
from typing import TYPE_CHECKING
from pathlib import Path
from novelwriter.error import logException
from novelwriter.common import formatTimeStamp
from novelwriter.constants import nwFiles
if TYPE_CHECKING:
from novelwriter.core.project import NWProject
logger = logging.getLogger(__name__)
class NWSessionLog:
"""Core: Session JSON Lines Log File
The class that wraps the session log file, which is in JSON Lines
format. That is, one JSON object per line.
"""
def __init__(self, project: NWProject):
self._project = project
self._start = 0.0
return
##
# Properties
##
@property
def start(self) -> float:
"""The session start time."""
return self._start
##
# Methods
##
def startSession(self):
"""Start the writng session."""
self._start = time()
return
def appendSession(self, idleTime: float) -> bool:
"""Append session statistics to the sessions log file."""
sessFile = self._project.storage.getMetaFile(nwFiles.SESS_FILE)
if not isinstance(sessFile, Path):
return False
now = time()
iNovel, iNotes = self._project.data.initCounts
cNovel, cNotes = self._project.data.currCounts
iTotal = iNovel + iNotes
wDiff = cNovel + cNotes - iTotal
sTime = now - self._start
logger.info("The session lasted %d sec and added %d words", int(sTime), wDiff)
if sTime < 300 and wDiff == 0:
logger.info("Session too short, skipping log entry")
return False
try:
if not sessFile.exists():
with open(sessFile, mode="w", encoding="utf-8") as fObj:
fObj.write(self.createInitial(iTotal))
with open(sessFile, mode="a+", encoding="utf-8") as fObj:
fObj.write(self.createRecord(
start=formatTimeStamp(self._start),
end=formatTimeStamp(now),
novel=cNovel,
notes=cNotes,
idle=round(idleTime)
))
except Exception:
logger.error("Failed to write to session stats file")
logException()
return False
return True
def createInitial(self, total: int) -> str:
"""Low level function to create the initial log file record."""
data = json.dumps({"type": "initial", "offset": total})
return f"{data}\n"
def createRecord(self, start: str, end: str, novel: int, notes: int, idle: int) -> str:
"""Low level function to create a log record."""
data = json.dumps({
"type": "record", "start": start, "end": end,
"novel": novel, "notes": notes, "idle": idle,
})
return f"{data}\n"
# END Class NWSessionLog