worldhopper/lib/models/opds_server.dart
Felipe M. 71651a6b21
All checks were successful
ci/woodpecker/pr/pr Pipeline was successful
feat: koreader sync
2026-02-15 13:00:48 +01:00

99 lines
3 KiB
Dart

import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:worldhopper/services/url_helper.dart';
part 'opds_server.freezed.dart';
part 'opds_server.g.dart';
/// Represents an OPDS server configuration
@freezed
class OPDSServer with _$OPDSServer {
const factory OPDSServer({
/// Unique identifier for the server
required String id,
/// Display name for the server
required String name,
/// Root URL of the OPDS server
required String url,
/// Optional username for HTTP Basic Auth
String? username,
/// Optional password for HTTP Basic Auth (stored encrypted in database)
String? password,
/// Timestamp when the server was added
required DateTime createdAt,
/// Timestamp of the last successful sync
DateTime? lastSyncedAt,
/// Whether KOReader sync is enabled for this server
@Default(false) bool koreaderSyncEnabled,
/// KOReader sync server URL (e.g., https://sync.example.com)
String? koreaderSyncUrl,
/// KOReader sync username
String? koreaderSyncUsername,
/// KOReader sync password
String? koreaderSyncPassword,
}) = _OPDSServer;
/// Create OPDSServer from JSON
factory OPDSServer.fromJson(Map<String, dynamic> json) =>
_$OPDSServerFromJson(json);
/// Create OPDSServer from database row
factory OPDSServer.fromDatabase(Map<String, dynamic> row) {
return OPDSServer(
id: row['id'] as String,
name: row['name'] as String,
url: row['url'] as String,
username: row['username'] as String?,
password: row['password'] as String?,
createdAt: DateTime.fromMillisecondsSinceEpoch(row['created_at'] as int),
lastSyncedAt: row['last_synced_at'] != null
? DateTime.fromMillisecondsSinceEpoch(row['last_synced_at'] as int)
: null,
koreaderSyncEnabled: (row['koreader_sync_enabled'] as int?) == 1,
koreaderSyncUrl: row['koreader_sync_url'] as String?,
koreaderSyncUsername: row['koreader_sync_username'] as String?,
koreaderSyncPassword: row['koreader_sync_password'] as String?,
);
}
}
extension OPDSServerX on OPDSServer {
/// Convert OPDSServer to database row
Map<String, dynamic> toDatabase() {
return {
'id': id,
'name': name,
'url': url,
'username': username,
'password': password,
'created_at': createdAt.millisecondsSinceEpoch,
'last_synced_at': lastSyncedAt?.millisecondsSinceEpoch,
'koreader_sync_enabled': koreaderSyncEnabled ? 1 : 0,
'koreader_sync_url': koreaderSyncUrl,
'koreader_sync_username': koreaderSyncUsername,
'koreader_sync_password': koreaderSyncPassword,
};
}
/// Check if server requires authentication
bool get requiresAuth => username != null && password != null;
/// Resolve a relative URL against this server's base URL
String resolveUrl(String relativeUrl) {
return UrlHelper.resolveUrl(url, relativeUrl);
}
/// Make a request URL by resolving it against the server base
String makeRequest(String path) {
return UrlHelper.resolveUrl(url, path);
}
}