Files
Telegram-Final-Project/src/main/java/org/to/telegramfinalproject/Client/DownloadsIndex.java
T
2025-08-15 00:31:26 +03:30

117 lines
3.9 KiB
Java

package org.to.telegramfinalproject.Client;
import org.json.JSONObject;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
public final class DownloadsIndex {
private final UUID accountId;
private final Path indexFile;
private final Map<UUID, Entry> map = new ConcurrentHashMap<>();
public DownloadsIndex(UUID accountId) {
this.accountId = accountId;
this.indexFile = resolveIndexPath(accountId.toString());
load();
}
private static Path resolveIndexPath(String accountId) {
String os = System.getProperty("os.name", "").toLowerCase();
String home = System.getProperty("user.home");
Path dir;
if (os.contains("win")) {
String appData = System.getenv("APPDATA");
dir = (appData != null)
? Paths.get(appData, "TeleSock")
: Paths.get(home, "AppData", "Roaming", "TeleSock");
} else {
dir = Paths.get(home, ".telesock");
}
try { Files.createDirectories(dir); } catch (IOException ignored) {}
return dir.resolve("downloads-index-" + accountId + ".json");
}
private synchronized void load() {
map.clear();
try {
if (!Files.exists(indexFile)) return;
String json = Files.readString(indexFile, StandardCharsets.UTF_8);
if (json == null || json.isBlank()) return;
JSONObject root = new JSONObject(json);
JSONObject items = root.optJSONObject("items");
if (items == null) return;
for (String key : items.keySet()) {
JSONObject e = items.getJSONObject(key);
map.put(UUID.fromString(key), new Entry(
e.getString("path"),
e.optLong("size", 0L),
e.optLong("ts", System.currentTimeMillis())
));
}
} catch (Exception e) {
System.err.println("⚠️ DownloadsIndex load failed: " + e.getMessage());
}
}
private synchronized void save() throws IOException {
JSONObject items = new JSONObject();
for (Map.Entry<UUID, Entry> it : map.entrySet()) {
JSONObject e = new JSONObject();
e.put("path", it.getValue().path);
e.put("size", it.getValue().size);
e.put("ts", it.getValue().ts);
items.put(it.getKey().toString(), e);
}
byte[] data = new JSONObject().put("items", items).toString(2).getBytes(StandardCharsets.UTF_8);
Path tmp = indexFile.resolveSibling(indexFile.getFileName() + ".tmp");
Files.write(tmp, data);
try {
Files.move(tmp, indexFile, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);
} catch (AtomicMoveNotSupportedException ex) {
Files.move(tmp, indexFile, StandardCopyOption.REPLACE_EXISTING);
}
}
public void saveQuietly() {
try { save(); } catch (Exception ignored) {}
}
public Path find(UUID mediaKey) {
Entry e = map.get(mediaKey);
if (e == null) return null;
Path p = Paths.get(e.path);
if (Files.exists(p)) return p;
map.remove(mediaKey);
saveQuietly();
return null;
}
public void put(UUID mediaKey, Path path, long size) {
map.put(mediaKey, new Entry(path.toString(), size, System.currentTimeMillis()));
saveQuietly();
}
public void remove(UUID mediaKey) {
map.remove(mediaKey);
saveQuietly();
}
private static final class Entry {
final String path; final long size; final long ts;
Entry(String path, long size, long ts) {
this.path = path; this.size = size; this.ts = ts;
}
}
}