different approach:
Code:
# -*- coding: utf-8 -*-
__license__ = 'GPL v3'
__copyright__ = '2025 Massimo Savazzi'
__my_version__ = "1.0.0" # Miscellany
"""
In order to manage Physical Books (.pbook) files, we define a Calibre plugin that treats .pbook files as ebooks.
It does import the info from the file and sets the metadata accordingly.
The .pbook file format is assumed to be a simple text file with key=value pairs, based on TOML e.g.:
[metadata]
title=Boook Title
author=Book Author
publisher=Book Publisher
ISBN=9788888888888
source=if scraped from a website, put the name here
publication_date=Book Publication Date
language=two-letter language code, e.g. it, en, fr
tag=Physical - all tags, comma-separated will be imported
"""
from calibre.customize import FileTypePlugin
class PBookEbookImporter(FileTypePlugin):
name = "PBook Importer"
description = "Import .pbook files reading the Metadata and updating it accordingly."
supported_platforms = ['windows', 'osx', 'linux']
version = (1, 0, 0)
author = 'Massimo Savazzi'
minimum_calibre_version = (6, 8, 0)
file_types = set(['pbook'])
ebook = True # <-- This makes Calibre treat .pbook as a real ebook
on_postimport = True
def postimport(self, book_id, book_format, db):
# Same metadata logic as before
path = db.format_path(book_id, book_format.upper(), index_is_id=True)
if not path:
return
meta = {}
in_meta = False
try:
with open(path, 'r', encoding='utf-8') as f:
lines = f.readlines()
except Exception:
with open(path, 'r', encoding='latin-1') as f:
lines = f.readlines()
for line in lines:
line = line.strip()
if line.lower() == '[metadata]':
in_meta = True
continue
if in_meta and line.startswith('['):
break
if in_meta and '=' in line:
k, v = line.split('=', 1)
meta[k.strip().lower()] = v.strip()
title = meta.get('title')
authors = [a.strip() for a in meta.get('author', '').replace(';', ',').split(',') if a.strip()] or None
publisher = meta.get('publisher')
source = meta.get('source')
tags = [t.strip() for t in meta.get('tag', '').split(',') if t.strip()] or None
language = [meta.get('language')] if meta.get('language') else None
identifiers = {}
if meta.get('isbn'):
identifiers['isbn'] = meta.get('isbn').replace('-', '').strip()
# Apply metadata
if authors: db.set_authors(book_id, authors, notify=True)
if title: db.set_title(book_id, title, notify=True)
if publisher: db.set_publisher(book_id, publisher, notify=True)
if source: db.set_tags(book_id, [source], notify=True) # optional: add source as tag
if tags: db.set_tags(book_id, tags, notify=True)
if language: db.set_languages(book_id, language, notify=True)
if identifiers: db.set_identifiers(book_id, identifiers, notify=True)
The only issue is that title sort is not correct as is equal to title