利用 floccus 自建导航页,极致压缩效率空间
编辑Floccus 是一个开源的浏览器书签同步工具,它允许用户在不同的浏览器之间同步书签,并且支持将书签同步到自己的 Nextcloud 或 WebDAV 服务器上,并且不会受限于特定的浏览器或平台。
我发现无论使用何种同步方式,Floccus 最终都会在目标服务器上生成一个资源文件来存储书签信息。通过解析资源文件,我自建了一个导航页用来展示书签,这样我在任意设备上都可以很方便的访问书签了,哪怕不是自己的设备。
接下来我不会分享导航页源码等内容,仅对如何访问和解密 Floccus 资源文件进行说明。大家可以根据自己的需求解析自己的资源文件,实现想要的功能。
访问资源文件
资源文件的储存位置与 Floccus 的设置有关,可以在 Floccus 选项中的服务器详细信息部分查看。Floccus 提供了 Nextcloud、WebDAV、Git over HTTPS 和 Google Drive 的同步方式。个人推荐使用自建的 WebDAV 服务器,这样资源文件直接储存在个人服务器硬盘上,访问方便且同步效率高。
如果使用其他同步方式或者资源文件未同步到本地服务器上,就需要通过HTTP或FTP协议使用API来访问资源文件。Nextcloud、WebDAV、Git over HTTPS和Google Drive这几种同步方式的API各不相同,需要自行研究。下面举例一个通过WebDAV访问资源文件的Java伪代码。
public static void main(String[] args) throws Exception {
//Webdav信息
String url = "https://dav.jianguoyun.com/dav/bookmark/bookmarks.xbel";
String username = "Webdav用户名";
String password = "Webdav密码";
//获取资源文件内容
String xmlDocStr = getFileString(url, username, password);
//TODO 实现其他逻辑
}
public static String getFileString(String url, String username, String password) {
try {
URL urlObj = new URL(url);
HttpsURLConnection connection = (HttpsURLConnection) urlObj.openConnection();
// Set basic authentication
String userCredentials = username + ":" + password;
String basicAuth = "Basic " + new String(java.util.Base64.getEncoder().encode(userCredentials.getBytes()));
connection.setRequestProperty("Authorization", basicAuth);
// Set request method
connection.setRequestMethod("GET");
// Disable SSL verification
connection.setSSLSocketFactory((javax.net.ssl.SSLSocketFactory) javax.net.ssl.SSLSocketFactory.getDefault());
connection.setHostnameVerifier((hostname, session) -> true);
// Get response
int responseCode = connection.getResponseCode();
if(responseCode != 200) {
return null;
}
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
return response.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
解密资源文件
这部分内容仅适用于在 Floccus 中设置过密码的资源文件。如果资源文件没有设置密码,则其内容就是明文的,可以直接解析。重要提醒:如果你设置了密码保护书签内容,务必确保不让其他人看到。同时,如果通过解密方式访问,请务必谨慎保管,以防泄密。
我参考了 Floccus 的源码文件:https://github.com/floccusaddon/floccus/blob/develop/src/lib/Crypto.ts。解密过程包括准备密钥、解码加密数据、提取初始化向量和密文部分、使用密钥和算法进行解密,最后将解密后的数据转换为可读格式。以下是解密资源文件的Java伪代码示例。
public static void main(String[] args) throws Exception {
//...
//获取资源文件内容
String xmlDocStr = getFileString(...);
//书签文件加密信息
String key = "Floccus中设置的密码";
String salt = "bookmarks.xbel";
//解密后输出到文件
Files.write("D://...", salt), decryptAES(key, xmlDocStr, salt).getBytes());
}
private static final int ITERATIONS = 250000;
private static final int IV_LENGTH = 16;
public static SecretKey prepareKey(String passphrase, String salt) throws Exception {
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
PBEKeySpec spec = new PBEKeySpec(passphrase.toCharArray(), salt.getBytes(StandardCharsets.UTF_8), ITERATIONS, 256);
SecretKey tmp = factory.generateSecret(spec);
return new SecretKeySpec(tmp.getEncoded(), "AES");
}
public static String decryptAES(String key, String payload, String salt) throws Exception {
SecretKey cryptoKey = prepareKey(key, salt);
byte[] buffer = Base64.getDecoder().decode(payload);
byte[] iv = Arrays.copyOfRange(buffer, 0, IV_LENGTH);
byte[] ciphertext = Arrays.copyOfRange(buffer, IV_LENGTH, buffer.length);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec spec = new GCMParameterSpec(128, iv);
cipher.init(Cipher.DECRYPT_MODE, cryptoKey, spec);
byte[] plaintextBytes = cipher.doFinal(ciphertext);
return new String(plaintextBytes, StandardCharsets.UTF_8);
}
解析资源文件
拿到明文资源文件后就只剩下解析了,Floccus 的资源文件格式目前分两种 XBEL 和 HTML,这也与你的设置有关。
更推荐使用XBEL格式,因为XBEL使用XML标记来表示书签数据,使得数据易于解析和处理。许多浏览器和书签管理工具都支持导入和导出XBEL格式的书签数据。以下是一段将XBEL解析为JSON格式的PHP代码,以便前端使用。
<?php
// 读取XML文件内容
$xmlString = file_get_contents("D:\\...\\bookmarks.xbel");
// 将文件内容转换为UTF-8编码
$xmlString = iconv(mb_detect_encoding($xmlString, mb_detect_order(), true), "UTF-8", $xmlString);
// 将XML字符串转换为SimpleXMLElement对象
$xml = simplexml_load_string($xmlString);
// 递归处理XML节点
function parseXml($xml) {
$result = [];
foreach ($xml->children() as $child) {
if ($child->getName() == 'folder') {
$node = [
'type' => 'folder',
'title' => (string) $child->title,
'children' => parseXml($child)
];
$result[] = $node;
} elseif ($child->getName() == 'bookmark' && trim((string)$child->title) !== '') {
$node = [
'type' => 'bookmark',
'title' => (string) $child->title,
'href' => (string) $child['href']
];
$result[] = $node;
}
}
return $result;
}
// 解析XML节点转换为JSON格式
$json = json_encode(array(
"title" => "根目录",
"type" => "folder",
"children" => parseXml($xml)
));
结束
通过以上方式,我们可以轻松地获取 Floccus 中保存的书签内容,并根据个人需求进行处理。如果你觉得这篇文章对你有帮助,那就太好了【你懂的】。
- 0
- 0
-
赞助
支付宝微信 -
分享