| package com.pt.service; |
| |
| import com.pt.entity.TorrentMeta; |
| import com.pt.repository.TorrentMetaRepository; |
| import com.pt.utils.BencodeCodec; |
| import org.springframework.beans.factory.annotation.Autowired; |
| import org.springframework.stereotype.Service; |
| |
| import java.security.MessageDigest; |
| import java.time.LocalDateTime; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Optional; |
| |
| @Service |
| public class TorrentService { |
| |
| @Autowired |
| private TorrentMetaRepository torrentMetaRepository; |
| |
| public TorrentMeta parseAndSaveTorrent(byte[] torrentBytes) throws Exception { |
| Map<String, Object> torrentDict = (Map<String, Object>) BencodeCodec.decode(torrentBytes); |
| if (!torrentDict.containsKey("info")) { |
| throw new IllegalArgumentException("Invalid torrent file: missing 'info' dictionary"); |
| } |
| |
| Map<String, Object> infoDict = (Map<String, Object>) torrentDict.get("info"); |
| // 计算 info_hash |
| byte[] infoEncoded = BencodeCodec.encode(infoDict); |
| MessageDigest sha1 = MessageDigest.getInstance("SHA-1"); |
| byte[] infoHashBytes = sha1.digest(infoEncoded); |
| String infoHash = bytesToHex(infoHashBytes); |
| // 获取文件名,大小等 |
| String name = (String) infoDict.get("name"); |
| long length = 0; |
| if (infoDict.containsKey("length")) { |
| length = ((Number) infoDict.get("length")).longValue(); |
| } else if (infoDict.containsKey("files")) { |
| long totalLength = 0; |
| List<Map<String, Object>> files = (List<Map<String, Object>>) infoDict.get("files"); |
| for (Map<String, Object> file : files) { |
| totalLength += ((Number) file.get("length")).longValue(); |
| } |
| length = totalLength; |
| } |
| // 添加Tracker地址到种子文件中 |
| torrentDict.put("announce", "http://your-tracker-url/api/tracker/announce"); |
| |
| // 保存到数据库 |
| Optional<TorrentMeta> existing = torrentMetaRepository.findByInfoHash(infoHash); |
| |
| if (existing.isPresent()) { |
| System.out.println("该种子已存在,跳过保存"); |
| return existing.get(); |
| } else { |
| TorrentMeta meta = new TorrentMeta(); |
| meta.setFilename(name); |
| meta.setInfoHash(infoHash); |
| meta.setSize(length); |
| meta.setUploadTime(LocalDateTime.now()); |
| meta.setTorrentData(BencodeCodec.encode(torrentDict)); // 使用更新后的字典编码 |
| |
| return torrentMetaRepository.save(meta); |
| } |
| |
| } |
| |
| |
| private String bytesToHex(byte[] bytes) { |
| StringBuilder sb = new StringBuilder(); |
| for (byte b : bytes) { |
| sb.append(String.format("%02x", b)); |
| } |
| return sb.toString(); |
| } |
| } |