117 lines
3.9 KiB
Java
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;
|
|
}
|
|
}
|
|
}
|