无标题无名氏No.62048096 只看PO
2024-04-16(二)05:45:25 ID:83YvGLK 回应
有人知道Tachiyomi的记录导出为json的方法吗?备份文件是 .tachibk,尝试直接更改扩展名为 .json,乱码;直接更改为 .zip,居然能看到部分中文,但是打开会卡住只能强行退出浏览app
无标题无名氏No.62076777
2024-04-18(四)14:11:38 ID: 4oFnDNS
gzip解压缩部分也可以直接用gzip -d 或者zcat或者gunzip 来解压,省去你写解压部分的代码
无标题无名氏No.62079375
2024-04-18(四)18:05:26 ID: CzzTJVo
>>No.62060237
你想简单粗暴就是直接git拉tachiyomi代码然后导入gradle项目,然后直接整个main方法调用现成的decode就完了,可能需要处理下Android包的问题
https://github.com/mihonapp/mihon/blob/main/app%2Fsrc%2Fmain%2Fjava%2Feu%2Fkanade%2Ftachiyomi%2Fdata%2Fbackup%2FBackupDecoder.kt
无标题无名氏No.62080352
2024-04-18(四)19:40:12 ID: MK1koCU
>>No.62076777
尝试了但没有成功。
备份文件的扩展名是 .tachibk,如果直接用 gzip -d *.tachibk 会提示 unknown suffix -- ignored,所以手动改扩展名为 .gz,得到了一个没有扩展名的二进制文件,然后从源码创建了以下 .protobuf 文件:
syntax = "proto3";
message Manga {
string url = 1;
string title = 2;
string artist = 3;
string author = 4;
string description = 5;
string genre = 6;
int32 status = 7;
string thumbnailUrl = 8;
bool favorite = 9;
string source = 10;
int64 dateAdded = 11;
int64 viewerFlags = 12;
int64 chapterFlags = 13;
string updateStrategy = 14;
int64 lastModifiedAt = 15;
int64 favoriteModifiedAt = 16;
int32 version = 17;
}
然后用 protoc --decode Manga manga.proto < myprotobin
但是得到:
[libprotobuf ERROR /tmp/protobuf-20230319-70010-1pqiw5q/protobuf-21.12/src/google/protobuf/wire_format_lite.cc:618] String field 'Manga.url' contains invalid UTF-8 data when parsing a protocol buffer. Use the 'bytes' type if you intend to send raw bytes.
Failed to parse input.
所以我修改 .protobuf 文件的 url 类型为 byte,但是得到的内容很短(明明有几千条记录),如下:
101 {
1: "\351\246\231\351\246\231\350\205\220\345\256\205"
2: 1471112097704477289
}
101 {
1: "Cartoon18"
2: 28664779574072063
}
绝对是没有解码成功,直接用 vscode 打开二进制文件还能看到中文的漫画标题呢,可是问题出在哪儿?
实在是没有思路了……
无标题无名氏No.62080386
2024-04-18(四)19:42:43 ID: 83YvGLK (PO主)
>>No.62079375
我看到哪个解码函数了,但是不懂安卓所以不知道怎么处理相关的包,对java了解实际上也不多,感觉还不如上面那个老哥的方法更容易些……
无标题无名氏No.62080402
2024-04-18(四)19:44:00 ID: 83YvGLK (PO主)
>>No.62080352
不是 .protobuf 文件,是 .proto 文件,以及 url 的类型 string会给错,byte和 bytes结果也都不大对……
无标题无名氏No.62080645
2024-04-18(四)20:02:28 ID: 83YvGLK (PO主)
目前最大的疑问是解压缩 gzip,明明扩展名不是 gzip文件,是不是手动修改扩展名这一步出了问题?
无标题无名氏No.62083994
2024-04-19(五)00:33:42 ID: CzzTJVo
我电脑没在身边,帮你问了下ai
Here's a Python implementation of a backup file decoder based on the provided Kotlin files. This implementation assumes that the backup file is in Protocol Buffers format and uses the `protobuf` library to decode it.
```python
import gzip
import protobuf
# Define the protobuf message classes
BackupManga = protobuf.Descriptors.BackupManga
BackupChapter = protobuf.Descriptors.BackupChapter
BackupCategory = protobuf.Descriptors.BackupCategory
BackupTracking = protobuf.Descriptors.BackupTracking
BackupHistory = protobuf.Descriptors.BackupHistory
BackupSource = protobuf.Descriptors.BackupSource
BackupPreference = protobuf.Descriptors.BackupPreference
BackupSourcePreferences = protobuf.Descriptors.BackupSourcePreferences
Backup = protobuf.Descriptors.Backup
def decode_backup(backup_file_path):
with open(backup_file_path, 'rb') as f:
content = f.read()
# Check if the file is gzipped
if content[:2] == b'\x1f\x8b':
content = gzip.decompress(content)
# Parse the protobuf message
backup = Backup.FromString(content)
# Process the backup data
print(f"Number of manga: {len(backup.backupManga)}")
for manga in backup.backupManga:
print(f"Manga: {manga.title}")
for chapter in manga.chapters:
print(f" Chapter: {chapter.name}")
print(f"Number of categories: {len(backup.backupCategories)}")
for category in backup.backupCategories:
print(f"Category: {category.name}")
print(f"Number of tracking entries: {sum(len(manga.tracking) for manga in backup.backupManga)}")
for manga in backup.backupManga:
for tracking in manga.tracking:
print(f"Tracking: {tracking.title}")
print(f"Number of history entries: {sum(len(manga.history) for manga in backup.backupManga)}")
for manga in backup.backupManga:
for history in manga.history:
print(f"History: {history.url}")
print(f"Number of sources: {len(backup.backupSources)}")
for source in backup.backupSources:
print(f"Source: {source.name}")
print(f"Number of preferences: {len(backup.backupPreferences)}")
for pref in backup.backupPreferences:
print(f"Preference: {pref.key} = {pref.value}")
print(f"Number of source preferences: {len(backup.backupSourcePreferences)}")
for source_prefs in backup.backupSourcePreferences:
print(f"Source preferences for {source_prefs.sourceKey}:")
for pref in source_prefs.prefs:
print(f" {pref.key} = {pref.value}")
if __name__ == "__main__":
backup_file_path = input("Enter the path to the backup file: ")
decode_backup(backup_file_path)
```
This program defines the Protobuf message classes based on the Kotlin classes provided. The `decode_backup` function takes the path to the backup file as input, opens the file, decompresses it if it's gzipped, and parses the Protobuf message using the `protobuf` library.
After parsing the backup data, the function processes and prints the various components of the backup, such as manga, chapters, categories, tracking entries, history entries, sources, preferences, and source preferences.
Note that you'll need to have the `protobuf` library installed to run this program. You can install it using `pip install protobuf`.
无标题无名氏No.62084003
2024-04-19(五)00:34:39 ID: CzzTJVo
> Give me an example of the descriptor file.
Unfortunately, I don't have access to the actual Protobuf descriptor file for the data structures defined in the provided Kotlin files. However, I can provide an example of what the descriptor file might look like based on the structure of the data classes.
```protobuf
syntax = "proto3";
package eu.kanade.tachiyomi.data.backup.models;
message BackupManga {
int64 source = 1;
string url = 2;
string title = 3;
string artist = 4;
string author = 5;
string description = 6;
repeated string genre = 7;
int32 status = 8;
string thumbnailUrl = 9;
int64 dateAdded = 13;
int32 viewer = 14;
repeated BackupChapter chapters = 16;
repeated int64 categories = 17;
repeated BackupTracking tracking = 18;
bool favorite = 100;
int32 chapterFlags = 101;
repeated BrokenBackupHistory brokenHistory = 102;
int32 viewerFlags = 103;
repeated BackupHistory history = 104;
int32 updateStrategy = 105;
int64 lastModifiedAt = 106;
int64 favoriteModifiedAt = 107;
repeated string excludedScanlators = 108;
int64 version = 109;
}
message BackupChapter {
string url = 1;
string name = 2;
string scanlator = 3;
bool read = 4;
bool bookmark = 5;
int64 lastPageRead = 6;
int64 dateFetch = 7;
int64 dateUpload = 8;
float chapterNumber = 9;
int64 sourceOrder = 10;
int64 lastModifiedAt = 11;
int64 version = 12;
}
// ... other message definitions for BackupCategory, BackupTracking, etc.
message Backup {
repeated BackupManga backupManga = 1;
repeated BackupCategory backupCategories = 2;
repeated BrokenBackupSource backupBrokenSources = 100;
repeated BackupSource backupSources = 101;
repeated BackupPreference backupPreferences = 104;
repeated BackupSourcePreferences backupSourcePreferences = 105;
}
```
This is a simplified example of what the Protobuf descriptor file might look like based on the data structures in the provided Kotlin files. Note that the field numbers and message names are derived from the Kotlin code, but the actual structure and naming conventions may differ in the real descriptor file.
In this example, each data class is represented as a Protobuf message, and the fields within each class are defined with their corresponding data types and field numbers. Nested classes are represented as nested messages within their parent message.