blob: 3c9d28df8a77248ea8355df687a6a9c741806f58 [file] [log] [blame]
22301102bc6da0a2025-06-02 17:47:29 +08001package com.pt.service;
2
3import com.pt.entity.TorrentMeta;
4import com.pt.repository.TorrentMetaRepository;
Edwardsamaxlf1bf7ad2025-06-03 23:52:16 +08005import com.pt.utils.BencodeCodec;
22301102bc6da0a2025-06-02 17:47:29 +08006import org.springframework.beans.factory.annotation.Autowired;
7import org.springframework.stereotype.Service;
8
22301102bc6da0a2025-06-02 17:47:29 +08009import java.security.MessageDigest;
10import java.time.LocalDateTime;
Edwardsamaxlf1bf7ad2025-06-03 23:52:16 +080011import java.util.List;
22301102bc6da0a2025-06-02 17:47:29 +080012import java.util.Map;
22301102ca0fb2f2025-06-09 18:40:42 +080013import java.util.Optional;
22301102bc6da0a2025-06-02 17:47:29 +080014
15@Service
16public class TorrentService {
17
22301102bc6da0a2025-06-02 17:47:29 +080018 @Autowired
19 private TorrentMetaRepository torrentMetaRepository;
20
Edwardsamaxlf1bf7ad2025-06-03 23:52:16 +080021 public TorrentMeta parseAndSaveTorrent(byte[] torrentBytes) throws Exception {
22 Map<String, Object> torrentDict = (Map<String, Object>) BencodeCodec.decode(torrentBytes);
23 if (!torrentDict.containsKey("info")) {
24 throw new IllegalArgumentException("Invalid torrent file: missing 'info' dictionary");
22301102bc6da0a2025-06-02 17:47:29 +080025 }
Edwardsamaxlf1bf7ad2025-06-03 23:52:16 +080026
27 Map<String, Object> infoDict = (Map<String, Object>) torrentDict.get("info");
Edwardsamaxlf1bf7ad2025-06-03 23:52:16 +080028 // 计算 info_hash
29 byte[] infoEncoded = BencodeCodec.encode(infoDict);
30 MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
31 byte[] infoHashBytes = sha1.digest(infoEncoded);
32 String infoHash = bytesToHex(infoHashBytes);
Edwardsamaxlf1bf7ad2025-06-03 23:52:16 +080033 // 获取文件名,大小等
34 String name = (String) infoDict.get("name");
35 long length = 0;
36 if (infoDict.containsKey("length")) {
37 length = ((Number) infoDict.get("length")).longValue();
38 } else if (infoDict.containsKey("files")) {
39 long totalLength = 0;
40 List<Map<String, Object>> files = (List<Map<String, Object>>) infoDict.get("files");
41 for (Map<String, Object> file : files) {
42 totalLength += ((Number) file.get("length")).longValue();
43 }
44 length = totalLength;
45 }
Edwardsamaxlf1bf7ad2025-06-03 23:52:16 +080046 // 保存到数据库
22301102ca0fb2f2025-06-09 18:40:42 +080047 Optional<TorrentMeta> existing = torrentMetaRepository.findByInfoHash(infoHash);
Edwardsamaxlf1bf7ad2025-06-03 23:52:16 +080048
22301102ca0fb2f2025-06-09 18:40:42 +080049 if (existing.isPresent()) {
50 System.out.println("该种子已存在,跳过保存");
51 return existing.get();
52 } else {
53 TorrentMeta meta = new TorrentMeta();
54 meta.setFilename(name);
55 meta.setInfoHash(infoHash);
56 meta.setSize(length);
57 meta.setUploadTime(LocalDateTime.now());
58 meta.setTorrentData(torrentBytes);
59
60 return torrentMetaRepository.save(meta);
61 }
62
22301102bc6da0a2025-06-02 17:47:29 +080063 }
64
Edwardsamaxlf1bf7ad2025-06-03 23:52:16 +080065
22301102bc6da0a2025-06-02 17:47:29 +080066 private String bytesToHex(byte[] bytes) {
67 StringBuilder sb = new StringBuilder();
68 for (byte b : bytes) {
69 sb.append(String.format("%02x", b));
70 }
71 return sb.toString();
72 }
Edwardsamaxlf1bf7ad2025-06-03 23:52:16 +080073}