From 82c6f12de286db3c89758f201f619a63accf17f4 Mon Sep 17 00:00:00 2001 From: "@syxhe" Date: Thu, 2 Oct 2025 16:21:29 -0500 Subject: Begin the over-engineering process --- .gitmodules | 3 ++ .idea/codeStyles/codeStyleConfig.xml | 5 ++ README.md | 26 ++++++++++- build.bash | 31 +++++++++++++ src/main/java/ChannelNode.java | 89 ++++++++++++++++++------------------ src/main/java/IChannelNode.java | 23 ++++++++-- td | 1 + 7 files changed, 130 insertions(+), 48 deletions(-) create mode 100644 .gitmodules create mode 100644 .idea/codeStyles/codeStyleConfig.xml create mode 100755 build.bash create mode 160000 td diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..b641dcc --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "td"] + path = td + url = https://github.com/tdlib/td diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..a55e7a1 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/README.md b/README.md index 61b4229..a592f5f 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,28 @@ ## Map the connections between Telegram channels using TDLib -TG Mapper is a tool for satiating my curiosity. For a long time, I've wanted to see how interconnected different TG channels are, and this is my solution. TG Mapper uses TDLib to search through channel posts, find forwarded posts, and store connections in a graph \ No newline at end of file +TG Mapper is a tool for satiating my curiosity. For a long time, I've wanted to see how interconnected different TG channels are, and this is my solution. TG Mapper uses TDLib to search through channel posts, find forwarded posts, and store connections in a graph + +## USAGE + +## DEPENDENCIES + +## BUILDING + +Clone repo & submodules: + +```bash +git clone --recurse-submodules https://git.dabikers.online/tgmapper +``` + +Move into dir and run build script + +```bash +./build.bash +``` + +This will output a .jar. Now, run the jar + +```bash +java run -jar tgmapper.jar +``` \ No newline at end of file diff --git a/build.bash b/build.bash new file mode 100755 index 0000000..f2b188d --- /dev/null +++ b/build.bash @@ -0,0 +1,31 @@ +#!/usr/bin/env -vS bash + +SOMEWHAT_REAL_DIR="$(realpath "$0")" +FILENAME="${SOMEWHAT_REAL_DIR##*/}" +PATH_TO="${SOMEWHAT_REAL_DIR/$FILENAME/}" + +function runInLocal() { + if [[ "$(pwd)/" != "$PATH_TO" ]]; then + (cd "$PATH_TO" && bash "$FILENAME") + exit $? + fi + + return 0 +} + +function buildTDLIB() { + + + return 0 +} + +function buildJar() { + + return 0 +} + +runInLocal && \ + buildTDLIB && \ + buildJar + +exit "$?" diff --git a/src/main/java/ChannelNode.java b/src/main/java/ChannelNode.java index ddc1488..20a7ac0 100644 --- a/src/main/java/ChannelNode.java +++ b/src/main/java/ChannelNode.java @@ -1,7 +1,6 @@ -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; +import static java.util.Map.entry; public class ChannelNode implements IChannelNode { private Map incoming; @@ -18,9 +17,10 @@ public class ChannelNode implements IChannelNode { if(dir == null) throw new IllegalArgumentException("direction is null"); if(conmap.containsKey(this)) throw new IllegalArgumentException("connection map contains this node"); - int dv = dir.getVal(); - if(dv >= Direction.INCOMING.getVal()) incoming = conmap; - if(dv >= Direction.OUTGOING.getVal()) outgoing = conmap; + Direction.overVals(Map.ofEntries( + entry(Direction.INCOMING, () -> incoming = conmap), + entry(Direction.OUTGOING, () -> outgoing = conmap) + ), dir); } @Override @@ -30,9 +30,10 @@ public class ChannelNode implements IChannelNode { if(dir == null) throw new IllegalArgumentException("dir is null"); if(num < 0) throw new IllegalArgumentException("num < 0"); - int dv = dir.getVal(); - if(dv >= Direction.INCOMING.getVal()) incoming.put(node, num); - if(dv >= Direction.OUTGOING.getVal()) outgoing.put(node, num); + Direction.overVals(Map.ofEntries( + entry(Direction.INCOMING, () -> incoming.put(node, num)), + entry(Direction.OUTGOING, () -> outgoing.put(node, num)) + ), dir); } @Override @@ -41,9 +42,10 @@ public class ChannelNode implements IChannelNode { if(node == this) throw new IllegalArgumentException("node is self"); if(dir == null) throw new IllegalArgumentException("dir is null"); - int dv = dir.getVal(); - if(dv >= Direction.INCOMING.getVal()) incoming.put(node, incoming.get(node) + 1); - if(dv >= Direction.OUTGOING.getVal()) outgoing.put(node, outgoing.get(node) + 1); + Direction.overVals(Map.ofEntries( + entry(Direction.INCOMING, () -> incoming.put(node, incoming.get(node) + 1)), + entry(Direction.OUTGOING, () -> outgoing.put(node, outgoing.get(node) + 1)) + ), dir); } @Override @@ -52,14 +54,12 @@ public class ChannelNode implements IChannelNode { if(dir == null) throw new IllegalArgumentException("dir is null"); nodes.forEach((node) -> {if(node == this) throw new IllegalArgumentException("one of the included nodes is this node");}); - int dv = dir.getVal(), - incomingV = Direction.INCOMING.getVal(), - outgoingV = Direction.OUTGOING.getVal(); - - nodes.forEach((node) -> { - if(dv >= incomingV) incoming.put(node, incoming.get(node) + 1); - if(dv >= outgoingV) outgoing.put(node, outgoing.get(node) + 1); - }); + for(IChannelNode node: nodes) { + Direction.overVals(Map.ofEntries( + entry(Direction.INCOMING, () -> incoming.put(node, incoming.get(node) + 1)), + entry(Direction.OUTGOING, () -> outgoing.put(node, outgoing.get(node) + 1)) + ), dir); + } } @Override @@ -68,9 +68,10 @@ public class ChannelNode implements IChannelNode { if(node == this) throw new IllegalArgumentException("node is self"); if(dir == null) throw new IllegalArgumentException("dir is null"); - int dv = dir.getVal(); - if(dv >= Direction.INCOMING.getVal()) incoming.put(node, Math.max(incoming.get(node) - 1, 0)); - if(dv >= Direction.OUTGOING.getVal()) outgoing.put(node, Math.max(outgoing.get(node) - 1, 0)); + Direction.overVals(Map.ofEntries( + entry(Direction.INCOMING, () -> incoming.put(node, Math.max(incoming.get(node) - 1, 0))), + entry(Direction.OUTGOING, () -> outgoing.put(node, Math.max(outgoing.get(node) - 1, 0))) + ), dir); } @Override @@ -79,23 +80,22 @@ public class ChannelNode implements IChannelNode { if(dir == null) throw new IllegalArgumentException("dir is null"); nodes.forEach((node) -> {if(node == this) throw new IllegalArgumentException("one of the included nodes is this node");}); - int dv = dir.getVal(), - incomingV = Direction.INCOMING.getVal(), - outgoingV = Direction.OUTGOING.getVal(); - - nodes.forEach((node) -> { - if(dv >= incomingV) incoming.put(node, Math.max(incoming.get(node) - 1, 0)); - if(dv >= outgoingV) outgoing.put(node, Math.max(outgoing.get(node) - 1, 0)); - }); + for(IChannelNode node: nodes) { + Direction.overVals(Map.ofEntries( + entry(Direction.INCOMING, () -> incoming.put(node, Math.max(incoming.get(node) - 1, 0))), + entry(Direction.OUTGOING, () -> outgoing.put(node, Math.max(outgoing.get(node) - 1, 0))) + ), dir); + } } @Override public void clearConnections(Direction dir) throws IllegalArgumentException { if(dir == null) throw new IllegalArgumentException("dir is null"); - int dv = dir.getVal(); - if(dv >= Direction.INCOMING.getVal()) incoming.clear(); - if(dv >= Direction.OUTGOING.getVal()) outgoing.clear(); + Direction.overVals(Map.ofEntries( + entry(Direction.INCOMING, () -> incoming.clear()), + entry(Direction.OUTGOING, () -> outgoing.clear()) + ), dir); } @Override @@ -115,12 +115,12 @@ public class ChannelNode implements IChannelNode { public int getNumConnections(Direction dir) throws IllegalArgumentException { if(dir == null) throw new IllegalArgumentException("dir is null"); - int total = 0; - int dv = dir.getVal(); - - if(dv >= Direction.INCOMING.getVal()) for(int i: incoming.values()) total += i; - if(dv >= Direction.OUTGOING.getVal()) for(int i: outgoing.values()) total += i; - return total; + AtomicInteger total = new AtomicInteger(); + Direction.overVals(Map.ofEntries( + entry(Direction.INCOMING, () -> {for(int i: incoming.values()) total.addAndGet(i);}), + entry(Direction.OUTGOING, () -> {for(int i: outgoing.values()) total.addAndGet(i);}) + ), dir); + return total.get(); } @Override @@ -137,10 +137,11 @@ public class ChannelNode implements IChannelNode { public List> getConnections(Direction dir) throws IllegalArgumentException { if(dir == null) throw new IllegalArgumentException("dir is null"); - int dv = dir.getVal(); ArrayList> res = new ArrayList<>(); - if(dv >= Direction.INCOMING.getVal()) res.add(incoming); - if(dv >= Direction.OUTGOING.getVal()) res.add(outgoing); + Direction.overVals(Map.ofEntries( + entry(Direction.INCOMING, () -> res.add(incoming)), + entry(Direction.OUTGOING, () -> res.add(outgoing)) + ), dir); return res; } diff --git a/src/main/java/IChannelNode.java b/src/main/java/IChannelNode.java index baf7572..a6446f1 100644 --- a/src/main/java/IChannelNode.java +++ b/src/main/java/IChannelNode.java @@ -3,13 +3,30 @@ import java.util.Map; public interface IChannelNode extends Comparable { enum Direction { - INCOMING(0), // Users incoming from outside channel (aka: other channel forwarded this channel's post) - OUTGOING(1), // Users outgoing from this channel (aka: this channel forwarded someone else's post) - BOTH(2); // Modify both incoming and outgoing counts at once + INCOMING(1), // Users incoming from outside channel (aka: other channel forwarded this channel's post) + OUTGOING(2), // Users outgoing from this channel (aka: this channel forwarded someone else's post) + BOTH(3); // Modify both incoming and outgoing counts at once private final int val; Direction(int val) {this.val = val;} public int getVal() {return this.val;} + + public interface callback { + void cb(); + } + public static void overVals(Map cmap, Direction dir) throws IllegalArgumentException { + if(cmap == null) throw new IllegalArgumentException("callback map is null"); + if(dir == null) throw new IllegalArgumentException("dir is null"); + for(Direction cdir: cmap.keySet()) if(cdir == null) throw new IllegalArgumentException("One of the directions is null"); + for(callback cb: cmap.values()) if(cb == null) throw new IllegalArgumentException("One of the callbacks is null"); + + // For each direction in the map, check that the given direction is gte, and if so run the callback + for(Direction cdir: cmap.keySet()) + if(dir.getVal() >= cdir.getVal()) + cmap.get(cdir).cb(); + } + // This is hilariously overengineered because java fucking sucks my entire cock and balls + // Barely even saves any space too } void setConnections(Map conmap, Direction dir); diff --git a/td b/td new file mode 160000 index 0000000..369ee92 --- /dev/null +++ b/td @@ -0,0 +1 @@ +Subproject commit 369ee922b45bfa7e8da357e4d62e93925862d86d -- cgit v1.2.3