Add a setting for document matching method
This commit is contained in:
@@ -54,6 +54,9 @@ bool KOReaderCredentialStore::saveToFile() const {
|
||||
// Write server URL
|
||||
serialization::writeString(file, serverUrl);
|
||||
|
||||
// Write match method
|
||||
serialization::writePod(file, static_cast<uint8_t>(matchMethod));
|
||||
|
||||
file.close();
|
||||
Serial.printf("[%lu] [KRS] Saved KOReader credentials to file\n", millis());
|
||||
return true;
|
||||
@@ -97,6 +100,15 @@ bool KOReaderCredentialStore::loadFromFile() {
|
||||
serverUrl.clear();
|
||||
}
|
||||
|
||||
// Read match method
|
||||
if (file.available()) {
|
||||
uint8_t method;
|
||||
serialization::readPod(file, method);
|
||||
matchMethod = static_cast<DocumentMatchMethod>(method);
|
||||
} else {
|
||||
matchMethod = DocumentMatchMethod::FILENAME;
|
||||
}
|
||||
|
||||
file.close();
|
||||
Serial.printf("[%lu] [KRS] Loaded KOReader credentials for user: %s\n", millis(), username.c_str());
|
||||
return true;
|
||||
@@ -148,3 +160,9 @@ std::string KOReaderCredentialStore::getBaseUrl() const {
|
||||
|
||||
return serverUrl;
|
||||
}
|
||||
|
||||
void KOReaderCredentialStore::setMatchMethod(DocumentMatchMethod method) {
|
||||
matchMethod = method;
|
||||
Serial.printf("[%lu] [KRS] Set match method: %s\n", millis(),
|
||||
method == DocumentMatchMethod::FILENAME ? "Filename" : "Binary");
|
||||
}
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
// Document matching method for KOReader sync
|
||||
enum class DocumentMatchMethod : uint8_t {
|
||||
FILENAME = 0, // Match by filename (simpler, works across different file sources)
|
||||
BINARY = 1, // Match by partial MD5 of file content (more accurate, but files must be identical)
|
||||
};
|
||||
|
||||
/**
|
||||
* Singleton class for storing KOReader sync credentials on the SD card.
|
||||
* Credentials are stored in /sd/.crosspoint/koreader.bin with basic
|
||||
@@ -11,7 +18,8 @@ class KOReaderCredentialStore {
|
||||
static KOReaderCredentialStore instance;
|
||||
std::string username;
|
||||
std::string password;
|
||||
std::string serverUrl; // Custom sync server URL (empty = default)
|
||||
std::string serverUrl; // Custom sync server URL (empty = default)
|
||||
DocumentMatchMethod matchMethod = DocumentMatchMethod::FILENAME; // Default to filename for compatibility
|
||||
|
||||
// Private constructor for singleton
|
||||
KOReaderCredentialStore() = default;
|
||||
@@ -51,6 +59,10 @@ class KOReaderCredentialStore {
|
||||
|
||||
// Get base URL for API calls (with https:// normalization, falls back to default)
|
||||
std::string getBaseUrl() const;
|
||||
|
||||
// Document matching method
|
||||
void setMatchMethod(DocumentMatchMethod method);
|
||||
DocumentMatchMethod getMatchMethod() const { return matchMethod; }
|
||||
};
|
||||
|
||||
// Helper macro to access credential store
|
||||
|
||||
@@ -4,6 +4,33 @@
|
||||
#include <MD5Builder.h>
|
||||
#include <SDCardManager.h>
|
||||
|
||||
namespace {
|
||||
// Extract filename from path (everything after last '/')
|
||||
std::string getFilename(const std::string& path) {
|
||||
const size_t pos = path.rfind('/');
|
||||
if (pos == std::string::npos) {
|
||||
return path;
|
||||
}
|
||||
return path.substr(pos + 1);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::string KOReaderDocumentId::calculateFromFilename(const std::string& filePath) {
|
||||
const std::string filename = getFilename(filePath);
|
||||
if (filename.empty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
MD5Builder md5;
|
||||
md5.begin();
|
||||
md5.add(filename.c_str());
|
||||
md5.calculate();
|
||||
|
||||
std::string result = md5.toString().c_str();
|
||||
Serial.printf("[%lu] [KODoc] Filename hash: %s (from '%s')\n", millis(), result.c_str(), filename.c_str());
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t KOReaderDocumentId::getOffset(int i) {
|
||||
// Offset = 1024 << (2*i)
|
||||
// For i = -1: 1024 >> 2 = 256
|
||||
|
||||
@@ -17,13 +17,22 @@
|
||||
class KOReaderDocumentId {
|
||||
public:
|
||||
/**
|
||||
* Calculate the KOReader document hash for a file.
|
||||
* Calculate the KOReader document hash for a file (binary/content-based).
|
||||
*
|
||||
* @param filePath Path to the file (typically an EPUB)
|
||||
* @return 32-character lowercase hex string, or empty string on failure
|
||||
*/
|
||||
static std::string calculate(const std::string& filePath);
|
||||
|
||||
/**
|
||||
* Calculate document hash from filename only (filename-based sync mode).
|
||||
* This is simpler and works when files have the same name across devices.
|
||||
*
|
||||
* @param filePath Path to the file (only the filename portion is used)
|
||||
* @return 32-character lowercase hex MD5 of the filename
|
||||
*/
|
||||
static std::string calculateFromFilename(const std::string& filePath);
|
||||
|
||||
private:
|
||||
// Size of each chunk to read at each offset
|
||||
static constexpr size_t CHUNK_SIZE = 1024;
|
||||
|
||||
Reference in New Issue
Block a user