View Single Post
Old 05-06-2020, 01:04 AM   #6
OrangeFlavored
Enthusiast
OrangeFlavored doesn't litterOrangeFlavored doesn't litter
 
Posts: 34
Karma: 100
Join Date: Oct 2014
Device: Likebook Mars
Experimented around with Calibre's database API as mentioned here and managed to set up a little CLI plugin to pull read percentage and last read time from a folder full of KOreader metadata into Calibre.

Code:
import os
import datetime
from dateutil.tz import tzlocal
from calibre.customize import Plugin
from calibre.library import db

class KoreaderPercentSync(Plugin):
	name                = 'KOreader Percent Sync'
	description         = 'Sync KOReader Percentage from command line'
	supported_platforms = ['windows', 'osx', 'linux']
	author              = 'Orange'
	version             = (0, 0, 3)
	minimum_calibre_version = (0, 7, 53)
		
	def cli_main(self, args):
		target = args[1]
		database = db(args[2]).new_api
		to_update_percent, to_update_date = {}, {}
		for root, dirs, files in os.walk(target):
			for target_folder in dirs:
				book = int(target_folder[:-4].rpartition(" - ")[2])
				calibre_percent = database.field_for("#perc_read", book)
				if calibre_percent != 1:
					percent, date = parse_metadata(os.path.join(root, target_folder, "metadata.epub.lua"))
					if not calibre_percent or abs(calibre_percent - percent) > 0.00001:
						to_update_percent[book] = percent
						to_update_date[book] = date
		database.set_field("#perc_read", to_update_percent)
		database.set_field("#last_read", to_update_date)
				
def parse_metadata(meta_file):
	with open(meta_file, "r") as metadata:
		percent = 0
		date = datetime.datetime.fromtimestamp(os.path.getmtime(meta_file), tzlocal())
		for line in metadata:
			read_line = line.strip()
			if read_line.startswith("[\"percent_finished\"]"):
				percent = read_line[23:-1]
			elif read_line == "[\"status\"] = \"complete\"":
				return (1, date)
		return (float(percent), date)
Works as a command line plugin taking two arguments for KOReader files & Calibre library location. For now expects files are named with the calibre ID at the end of the file/folder name separated by " - ". .txt files with timestamp no longer needed since I finally figured a way to move the files to my PC from my e-reader without messing with the timestamps on the files themselves...

Last edited by OrangeFlavored; 05-27-2020 at 03:12 PM.
OrangeFlavored is offline   Reply With Quote