mirror of
https://github.com/vishalxl/nostr_console.git
synced 2025-09-18 17:40:34 +02:00
fixed json decode issue. added more profile info including distance. added search by client
This commit is contained in:
@@ -132,20 +132,23 @@ Future<void> main(List<String> arguments) async {
|
||||
//stdout.write("Got argument request: ${argResults[requestArg]}");
|
||||
stdout.write('Sending request and waiting for events...');
|
||||
|
||||
sendRequest(defaultServerUrl, argResults[requestArg]);
|
||||
sendRequest(gListRelayUrls, argResults[requestArg]);
|
||||
Future.delayed(const Duration(milliseconds: 6000), () {
|
||||
List<Event> receivedEvents = getRecievedEvents();
|
||||
stdout.write("received ${receivedEvents.length - numFileEvents} events from $defaultServerUrl\n");
|
||||
stdout.write("received ${receivedEvents.length - numFileEvents} events\n");
|
||||
|
||||
// remove bots
|
||||
receivedEvents.removeWhere((e) => gBots.contains(e.eventData.pubkey));
|
||||
|
||||
// create tree
|
||||
Tree node = getTree(getRecievedEvents());
|
||||
clearEvents(); // cause we have consumed them above
|
||||
|
||||
Future<Tree> node = getTree(getRecievedEvents());
|
||||
//clearEvents(); // cause we have consumed them above
|
||||
node.then((value) {
|
||||
clearEvents();
|
||||
mainMenuUi(value, []);
|
||||
});
|
||||
// call main menu
|
||||
mainMenuUi(node, []);
|
||||
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -216,11 +219,14 @@ Future<void> main(List<String> arguments) async {
|
||||
stdout.write("received $numOtherEvents other posts\n");
|
||||
|
||||
// get all events in Tree form
|
||||
Tree node = getTree(getRecievedEvents());
|
||||
clearEvents();
|
||||
Future<Tree> node = getTree(getRecievedEvents());
|
||||
|
||||
// call the mein UI function
|
||||
mainMenuUi(node, contactList);
|
||||
node.then((value) {
|
||||
clearEvents();
|
||||
mainMenuUi(value, contactList);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -120,7 +120,8 @@ Future<void> otherMenuUi(Tree node, var contactList) async {
|
||||
'Rebroadcast an event', // 6
|
||||
'Applicatoin stats', // 7
|
||||
'Help and About', // 8
|
||||
'Go back to main menu'], // 9
|
||||
'Go back to main menu', // 9
|
||||
'Search by client'],
|
||||
"Other Menu"); // menu name
|
||||
print('You picked: $option');
|
||||
switch(option) {
|
||||
@@ -237,9 +238,19 @@ Future<void> otherMenuUi(Tree node, var contactList) async {
|
||||
// if contact list was found, get user's feed, and keep the contact list for later use
|
||||
String authorName = getAuthorName(pubkey.first);
|
||||
List<String> contactList = [];
|
||||
print("\nShowing the profile page for ${pubkey.first} ($authorName), whose contact list has ${ (contactEvent?.eventData.contactList.length)??0} profiles.\n ");
|
||||
print("\nShowing the profile page for ${pubkey.first} ($authorName).\n");
|
||||
if (contactEvent != null ) {
|
||||
print("The account follows ${contactEvent.eventData.contactList.length} accounts:");
|
||||
|
||||
contactEvent.eventData.contactList.forEach((x) => stdout.write("${getAuthorName(x.id)}, "));
|
||||
List<String> followers = node.getFollowers(pubkey.first);
|
||||
|
||||
print("\n\nThe account has ${followers.length} followers: ");
|
||||
|
||||
followers.forEach((x) => stdout.write("${getAuthorName(x)}, "));
|
||||
|
||||
// print social distance info.
|
||||
node.printSocialDistance(pubkey.first, authorName);
|
||||
}
|
||||
print("");
|
||||
}
|
||||
@@ -255,6 +266,7 @@ Future<void> otherMenuUi(Tree node, var contactList) async {
|
||||
node.printTree(0, DateTime.now().subtract(Duration(days:gNumLastDays)), onlyWords); // search for last gNumLastDays only
|
||||
}
|
||||
break;
|
||||
|
||||
case 6:
|
||||
print("TBD");
|
||||
break;
|
||||
@@ -286,6 +298,16 @@ Future<void> otherMenuUi(Tree node, var contactList) async {
|
||||
continueOtherMenu = false;
|
||||
break;
|
||||
|
||||
case 10:
|
||||
stdout.write("Enter client name whose events you want to see: ");
|
||||
String? $tempWords = stdin.readLineSync();
|
||||
String clientName = $tempWords??"";
|
||||
if( clientName != "") {
|
||||
bool fromClient (Tree t) => t.fromClientSelector(clientName);
|
||||
node.printTree(0, DateTime.now().subtract(Duration(days:gNumLastDays)), fromClient); // search for last gNumLastDays only
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@@ -301,7 +301,7 @@ class EventData {
|
||||
int n = 4;
|
||||
String maxN(String v) => v.length > n? v.substring(0,n) : v.substring(0, v.length);
|
||||
void printInColor(String s, String commentColor) => stdout.supportsAnsiEscapes ?stdout.write("$commentColor$s$colorEndMarker"):stdout.write(s);
|
||||
|
||||
|
||||
DateTime dTime = DateTime.fromMillisecondsSinceEpoch(createdAt *1000);
|
||||
|
||||
// TODO do it in one call
|
||||
@@ -592,3 +592,4 @@ Set<String> getPublicKeyFromName(String userName) {
|
||||
|
||||
return pubkeys;
|
||||
}
|
||||
|
||||
|
@@ -263,8 +263,10 @@ void getMultiUserEvents(serverUrl, List<String> publicKeys, numUserEvents) {
|
||||
}
|
||||
}
|
||||
|
||||
void sendRequest(serverUrl, request) {
|
||||
relays.sendRequest(serverUrl, request);
|
||||
void sendRequest(List<String> serverUrls, request) {
|
||||
for(int i = 0; i < serverUrls.length; i++) {
|
||||
relays.sendRequest(serverUrls[i], request);
|
||||
}
|
||||
}
|
||||
|
||||
List<Event> getRecievedEvents() {
|
||||
@@ -273,6 +275,7 @@ List<Event> getRecievedEvents() {
|
||||
|
||||
void clearEvents() {
|
||||
relays.rEvents = [];
|
||||
if( gDebug > 0) print("clearEvents(): returning");
|
||||
}
|
||||
|
||||
void setRelaysIntialEvents(eventsFromFile) {
|
||||
|
152
lib/tree_ds.dart
152
lib/tree_ds.dart
@@ -34,6 +34,7 @@ class Tree {
|
||||
events.forEach((event) {
|
||||
// only add in map those kinds that are supported or supposed to be added ( 0 1 3 7 40)
|
||||
//if( event.eventData.kind == 40 || event.eventData.kind == 42) if( gDebug > 0) print("in from Events: got a kind 40/42 event of id ${event.eventData.id} and kind ${event.eventData.kind}" );
|
||||
//event.printEvent(0);
|
||||
if( typesInEventMap.contains(event.eventData.kind)) {
|
||||
tempChildEventsMap[event.eventData.id] = Tree(event, [], {}, [], false, {});
|
||||
}
|
||||
@@ -45,6 +46,8 @@ class Tree {
|
||||
List<String> tempWithoutParent = [];
|
||||
Map<String, ChatRoom> rooms = {};
|
||||
|
||||
if( gDebug > 0) print("In from Events: size of tempChildEventsMap = ${tempChildEventsMap.length} ");
|
||||
|
||||
tempChildEventsMap.forEach((key, value) {
|
||||
String eId = value.e.eventData.id;
|
||||
int eKind = value.e.eventData.kind;
|
||||
@@ -71,20 +74,42 @@ class Tree {
|
||||
}
|
||||
|
||||
if(eKind == 40) {
|
||||
//print("Processing type 40");
|
||||
String chatRoomId = eId;
|
||||
dynamic json = jsonDecode(value.e.eventData.content);
|
||||
try {
|
||||
//print("Processing type 40 json");
|
||||
dynamic json = jsonDecode(value.e.eventData.content);
|
||||
//print("Processed type 40 json");
|
||||
|
||||
if( rooms.containsKey(chatRoomId)) {
|
||||
if( rooms[chatRoomId]?.name == "") {
|
||||
if( gDebug > 0) print('Added room name = ${json['name']} for $chatRoomId' );
|
||||
rooms[chatRoomId]?.name = json['name'];
|
||||
if( rooms.containsKey(chatRoomId)) {
|
||||
//print("in if chatRoomId key in rooms");
|
||||
if( rooms[chatRoomId]?.name == "") {
|
||||
if( gDebug > 0) print('Added room name = ${json['name']} for $chatRoomId' );
|
||||
rooms[chatRoomId]?.name = json['name'];
|
||||
}
|
||||
} else {
|
||||
List<String> temp = [];
|
||||
//temp.add(eId);
|
||||
//print("in else");
|
||||
//print("json = $json");
|
||||
|
||||
String roomName = "", roomAbout = "";
|
||||
|
||||
if( json.containsKey('name') ) {
|
||||
roomName = json['name'];
|
||||
}
|
||||
|
||||
if( json.containsKey('about')) {
|
||||
roomAbout = json['about'];
|
||||
}
|
||||
|
||||
ChatRoom room = ChatRoom(chatRoomId, roomName, roomAbout, "", []);
|
||||
rooms[chatRoomId] = room;
|
||||
if( gDebug > 0) print("Added new chat room $chatRoomId with name ${json['name']} .");
|
||||
}
|
||||
} else {
|
||||
List<String> temp = [];
|
||||
//temp.add(eId);
|
||||
ChatRoom room = ChatRoom(chatRoomId, json['name'], json['about'], "", []);
|
||||
rooms[chatRoomId] = room;
|
||||
if( gDebug > 0) print("Added new chat room $chatRoomId with name ${json['name']} .");
|
||||
|
||||
} on Exception catch(e) {
|
||||
if( gDebug > 0) print("In From Event. Event type 40. Json Decode error for event id ${value.e.eventData.id}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -671,14 +696,13 @@ class Tree {
|
||||
return true;
|
||||
}
|
||||
for( int i = 0; i < children.length; i++ ) {
|
||||
if( children[i].hasUserPost(pubkey)) {
|
||||
if( children[i].hasUserPostAndLike(pubkey)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// returns true if the given words exists in it or its children
|
||||
bool hasWords(String word) {
|
||||
//if(gDebug > 0) print("In tree selector hasWords: this id = ${e.eventData.id} word = $word");
|
||||
@@ -689,6 +713,7 @@ class Tree {
|
||||
if( e.eventData.content.toLowerCase().contains(word)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for( int i = 0; i < children.length; i++ ) {
|
||||
//if(gDebug > 0) print("this id = ${e.eventData.id} word = $word i = $i ");
|
||||
|
||||
@@ -697,13 +722,38 @@ class Tree {
|
||||
continue;
|
||||
}
|
||||
|
||||
if( children[i].e.eventData.content.toLowerCase().contains(word)) {
|
||||
if( children[i].hasWords(word)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// returns true if the event or any of its children were made from the given client, and they are marked for notification
|
||||
bool fromClientSelector(String clientName) {
|
||||
//if(gDebug > 0) print("In tree selector hasWords: this id = ${e.eventData.id} word = $word");
|
||||
|
||||
List<List<String>> tags = e.eventData.tags;
|
||||
for( int i = 0; i < tags.length; i++) {
|
||||
if( tags[i].length < 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if( tags[i][0] == "client" && tags[i][1].contains(clientName)) {
|
||||
e.eventData.isNotification = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for( int i = 0; i < children.length; i++ ) {
|
||||
if( children[i].fromClientSelector(clientName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Event? getContactEvent(String pkey) {
|
||||
|
||||
// get the latest kind 3 event for the user, which lists his 'follows' list
|
||||
@@ -729,6 +779,77 @@ class Tree {
|
||||
return null;
|
||||
}
|
||||
|
||||
//void create
|
||||
|
||||
List<String> getFollowers(String pubkey) {
|
||||
if( gDebug > 0) print("Finding followrs for $pubkey");
|
||||
List<String> followers = [];
|
||||
|
||||
Set<String> usersWithContactList = {};
|
||||
allChildEventsMap.forEach((key, value) {
|
||||
if( value.e.eventData.kind == 3) {
|
||||
usersWithContactList.add(value.e.eventData.pubkey);
|
||||
}
|
||||
});
|
||||
|
||||
usersWithContactList.forEach((x) {
|
||||
Event? contactEvent = getContactEvent(x);
|
||||
|
||||
if( contactEvent != null) {
|
||||
List<Contact> contacts = contactEvent.eventData.contactList;
|
||||
for(int i = 0; i < contacts.length; i ++) {
|
||||
if( contacts[i].id == pubkey) {
|
||||
followers.add(x);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return followers;
|
||||
}
|
||||
|
||||
void printSocialDistance(String otherPubkey, String otherName) {
|
||||
String otherName = getAuthorName(otherPubkey);
|
||||
|
||||
List<String> contactList = [];
|
||||
Event? contactEvent = this.getContactEvent(userPublicKey);
|
||||
bool isFollow = false;
|
||||
int numSecond = 0; // number of your follows who follow the other
|
||||
|
||||
int numContacts = 0;
|
||||
if( contactEvent != null) {
|
||||
List<Contact> contacts = contactEvent.eventData.contactList;
|
||||
numContacts = contacts.length;
|
||||
for(int i = 0; i < contacts.length; i ++) {
|
||||
// check if you follow the other account
|
||||
if( contacts[i].id == otherPubkey) {
|
||||
isFollow = true;
|
||||
}
|
||||
// count the number of your contacts who know or follow the other account
|
||||
List<Contact> followContactList = [];
|
||||
Event? followContactEvent = this.getContactEvent(contacts[i].id);
|
||||
if( followContactEvent != null) {
|
||||
followContactList = followContactEvent.eventData.contactList;
|
||||
for(int j = 0; j < followContactList.length; j++) {
|
||||
if( followContactList[j].id == otherPubkey) {
|
||||
numSecond++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}// end for loop through users contacts
|
||||
print("\n\n");
|
||||
if( isFollow) {
|
||||
print("* You follow $otherName ");
|
||||
}
|
||||
|
||||
print("* Of the $numContacts people you follow, $numSecond follow $otherName");
|
||||
|
||||
} // end if contact event was found
|
||||
}
|
||||
|
||||
|
||||
} // end Tree
|
||||
|
||||
void addMessageToChannel(String channelId, String messageId, var tempChildEventsMap, var chatRooms) {
|
||||
@@ -829,10 +950,11 @@ void processReactions(List<Event> events) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @function getTree Creates a Tree out of these received List of events.
|
||||
*/
|
||||
Tree getTree(List<Event> events) {
|
||||
Future<Tree> getTree(List<Event> events) async {
|
||||
if( events.isEmpty) {
|
||||
print("Warning: In printEventsAsTree: events length = 0");
|
||||
return Tree(Event("","",EventData("non","", 0, 0, "", [], [], [], [[]], {}), [""], "[json]"), [], {}, [], true, {});
|
||||
|
Reference in New Issue
Block a user