Move session log handling to a separate class, and use jsonl format
This commit is contained in:
@@ -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 2018–2023, 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
|
||||
Reference in New Issue
Block a user