added utils.dart

moved string related and other such code to utils.dart
This commit is contained in:
Vishal 2022-11-28 12:09:37 +05:30
parent c54e36c603
commit f1ab310630
7 changed files with 247 additions and 229 deletions

View File

@ -4,6 +4,7 @@ import 'package:nostr_console/event_ds.dart';
import 'package:nostr_console/tree_ds.dart';
import 'package:nostr_console/relays.dart';
import 'package:nostr_console/settings.dart';
import 'package:nostr_console/utils.dart';
import 'package:bip340/bip340.dart';
import 'package:qr/qr.dart';
@ -1474,9 +1475,6 @@ Future<void> socialMenuUi(Store node) async {
} // end while
} // end mainMenuUi()
void showInitialNotifications(Store node) {
bool hasNotifications (Tree t) => t.treeSelectorNotifications();

View File

@ -4,6 +4,7 @@ import 'dart:math';
import 'package:bip340/bip340.dart';
import 'package:intl/intl.dart';
import 'package:nostr_console/tree_ds.dart';
import 'package:nostr_console/utils.dart';
import 'package:translator/translator.dart';
import 'package:crypto/crypto.dart';
import 'package:nostr_console/settings.dart';
@ -13,7 +14,6 @@ import "package:pointycastle/export.dart";
import 'package:kepler/kepler.dart';
import 'package:http/http.dart' as http;
String getStrInColor(String s, String commentColor) => stdout.supportsAnsiEscapes ?"$commentColor$s$gColorEndMarker":s;
void printInColor(String s, String commentColor) => stdout.supportsAnsiEscapes ?stdout.write("$commentColor$s$gColorEndMarker"):stdout.write(s);
void printWarning(String s) => stdout.supportsAnsiEscapes ?stdout.write("$gWarningColor$s$gColorEndMarker\n"):stdout.write("$s\n");
@ -54,42 +54,6 @@ Map< String, List<List<String>> > gReactions = {};
// is updated as kind 3 events are received
Map< String, List<Contact>> gContactLists = {};
String myPadRight(String str, int width) {
String newStr = "";
if( str.length < width) {
newStr = str.padRight(width);
} else {
newStr = str.substring(0, width);
}
return newStr;
}
// returns tags as string that can be used to calculate event has. called from EventData constructor
String getStrTagsFromJson(dynamic json) {
String str = "";
int i = 0;
for( dynamic tag in json ) {
if( i != 0) {
str += ",";
}
str += "[";
int j = 0;
for(dynamic element in tag) {
if( j != 0) {
str += ",";
}
str += "\"${element.toString()}\"";
j++;
}
str += "]";
i++;
}
return str;
}
bool verifyEvent(dynamic json) {
return true;
@ -1000,21 +964,6 @@ void addToHistogram(Map<String, int> histogram, List<String> pTags) {
//return histogram;
}
class HistogramEntry {
String str;
int count;
HistogramEntry(this.str, this.count);
static int histogramSorter(HistogramEntry a, HistogramEntry b) {
if( a.count < b.count ) {
return 1;
} if( a.count == b.count ) {
return 0;
} else {
return -1;
}
}
}
// return the numMostFrequent number of most frequent p tags ( user pubkeys) in the given events
List<String> getpTags(Set<Event> events, int numMostFrequent) {
List<HistogramEntry> listHistogram = [];
@ -1268,7 +1217,6 @@ int getSecondsDaysAgo( int N) {
return DateTime.now().subtract(Duration(days: N)).millisecondsSinceEpoch ~/ 1000;
}
void printUnderlined(String x) => { stdout.write("$x\n${getNumDashes(x.length)}\n")};
void printDepth(int d) {
for( int i = 0; i < gSpacesPerDepth * d + gNumLeftMarginSpaces; i++) {
@ -1294,34 +1242,6 @@ String getDepthSpaces(int d) {
return str;
}
String getNumSpaces(int num) {
String s = "";
for( int i = 0; i < num; i++) {
s += " ";
}
return s;
}
String getNumDashes(int num, [String dashType = "-"]) {
String s = "";
for( int i = 0; i < num; i++) {
s += dashType;
}
return s;
}
List<List<int>> getUrlRanges(String s) {
List<List<int>> urlRanges = [];
String regexp1 = "http[s]*:\/\/[a-zA-Z0-9]+([.a-zA-Z0-9/_\\-\\#\\+=\\&\\?]*)";
RegExp httpRegExp = RegExp(regexp1);
for( var match in httpRegExp.allMatches(s) ) {
List<int> entry = [match.start, match.end];
urlRanges.add(entry);
}
return urlRanges;
}
// make a paragraph of s that starts at numSpaces ( from screen left), and does not extend beyond gTextWidth+gNumLeftMarginSpaces. break it, or add
// a newline if it goes beyond gTextWidth + gNumLeftMarginSpaces
@ -1351,16 +1271,6 @@ String makeParagraphAtDepth(String s, int depthInSpaces) {
return newString;
}
// returns true if n is in any of the ranges given in list
int isInRange( int n, List<List<int>> ranges ) {
for( int i = 0; i < ranges.length; i++) {
if( n >= ranges[i][0] && n < ranges[i][1]) {
return ranges[i][1];
}
}
return 0;
}
// returns from string[startIndex:] the first len number of chars. no newline is added.
List getLineWithMaxLen(String s, int startIndex, int lenPerLine, String spacesString, List<List<int>> urlRanges) {
@ -1431,104 +1341,6 @@ List getLineWithMaxLen(String s, int startIndex, int lenPerLine, String spacesSt
return [line, i - startIndex];
}
bool nonEnglish(String str) {
bool result = false;
return result;
}
bool isNumeric(String s) {
return double.tryParse(s) != null;
}
bool isWordSeparater(String s) {
if( s.length != 1) {
return false;
}
return s[0] == ' ' || s[0] == '\n' || s[0] == '\r' || s[0] == '\t'
|| s[0] == ',' || s[0] == '.' || s[0] == '-' || s[0] == '('|| s[0] == ')';
}
bool isWhitespace(String s) {
if( s.length != 1) {
return false;
}
return s[0] == ' ' || s[0] == '\n' || s[0] == '\r' || s[0] == '\t';
}
extension StringX on String {
int isChannelPageNumber(int max) {
if(this.length < 2 || this[0] != '/') {
return 0;
}
String rest = this.substring(1);
//print("rest = $rest");
int? n = int.tryParse(rest);
if( n != null) {
if( n < max)
return n;
}
return 0;
}
isEnglish( ) {
// since smaller words can be smileys they should not be translated
if( length < 10)
return true;
if( !isLatinAlphabet())
return false;
if (isRomanceLanguage())
return false;
return true;
}
isPortugese() {
false; // https://1000mostcommonwords.com/1000-most-common-portuguese-words/
}
bool isRomanceLanguage() {
// https://www.thoughtco.com/most-common-french-words-1372759
Set<String> frenchWords = {"oui", "je", "le", "un", "de", "merci", "une", "ce", "pas"}; // "et" is in 'et al'
Set<String> spanishWords = {"y", "se", "el", "uso", "que", "te", "los", "va", "ser", "si", "por", "lo", "es", "era", "un", "o"};
Set<String> portugeseWords = {"como", "seu", "que", "ele", "foi", "eles", "tem", "este", "por", "quente", "vai",
"ter", "mas", "ou", "teve", "fora", "é", "te", "mais"};
Set<String> romanceWords = frenchWords.union(spanishWords).union(portugeseWords);
for( String word in romanceWords) {
if( this.toLowerCase().contains(" $word ")) {
if( gDebug > 0) print("isRomanceLanguage: Found ${this.toString()} is romance language");
return true;
}
}
return false;
}
isLatinAlphabet({caseSensitive = false}) {
int countLatinletters = 0;
for (int i = 0; i < length; i++) {
final target = caseSensitive ? this[i] : this[i].toLowerCase();
if ( (target.codeUnitAt(0) > 96 && target.codeUnitAt(0) < 123) || ( isNumeric(target) ) || isWhitespace(target)) {
countLatinletters++;
}
}
if( countLatinletters < ( 40.0/100 ) * length ) {
if( gDebug > 0) print("in isLatinAlphabet: latin letters: $countLatinletters and total = $length ");
return false;
} else {
return true;
}
}
}
// The contact only stores id and relay of contact. The actual name is stored in a global variable/map
class Contact {
@ -1542,23 +1354,6 @@ class Contact {
}
String addEscapeChars(String str) {
String temp = "";
//temp = temp.replaceAll("\\", "\\\\");
temp = str.replaceAll("\"", "\\\"");
return temp.replaceAll("\n", "\\n");
}
String unEscapeChars(String str) {
//print("in unEscape: |$str|");
String temp = str.replaceAll("\"", "\\\"");
//temp = temp.replaceAll("\\\\", "\\");
temp = temp.replaceAll("\n", "\\n");
//print("returning |$temp|\n");
return temp;
}
String getShaId(String pubkey, String createdAt, String kind, String strTags, String content) {
String buf = '[0,"$pubkey",$createdAt,$kind,[$strTags],"$content"]';
if(gSpecificDebug > 0) print("in getShaId for buf: |$buf|");
@ -1777,14 +1572,6 @@ Set<Event> readEventsFromFile(String filename) {
return events;
}
bool isValidPubkey(String pubkey) {
if( pubkey.length == 64) {
return true;
}
return false;
}
List<String> getEncryptedChannelKeys(List<String> secretMessageIds, Map<String, Tree> tempChildEventsMap, String channelId) {
Event? e = tempChildEventsMap[channelId]?.event;

View File

@ -2,6 +2,7 @@ import 'dart:io';
import 'dart:convert';
import 'package:nostr_console/event_ds.dart';
import 'package:nostr_console/settings.dart';
import 'package:nostr_console/utils.dart';
import 'package:web_socket_channel/io.dart';
class Relay {

View File

@ -3,6 +3,7 @@ import 'dart:convert';
import 'package:nostr_console/event_ds.dart';
import 'package:nostr_console/relays.dart';
import 'package:nostr_console/settings.dart';
import 'package:nostr_console/utils.dart';
typedef fTreeSelector = bool Function(Tree a);
typedef fRoomSelector = bool Function(ScrollableMessages room);

218
lib/utils.dart Normal file
View File

@ -0,0 +1,218 @@
import 'dart:io';
class HistogramEntry {
String str;
int count;
HistogramEntry(this.str, this.count);
static int histogramSorter(HistogramEntry a, HistogramEntry b) {
if( a.count < b.count ) {
return 1;
} if( a.count == b.count ) {
return 0;
} else {
return -1;
}
}
}
bool nonEnglish(String str) {
bool result = false;
return result;
}
bool isNumeric(String s) {
return double.tryParse(s) != null;
}
bool isWordSeparater(String s) {
if( s.length != 1) {
return false;
}
return s[0] == ' ' || s[0] == '\n' || s[0] == '\r' || s[0] == '\t'
|| s[0] == ',' || s[0] == '.' || s[0] == '-' || s[0] == '('|| s[0] == ')';
}
bool isWhitespace(String s) {
if( s.length != 1) {
return false;
}
return s[0] == ' ' || s[0] == '\n' || s[0] == '\r' || s[0] == '\t';
}
extension StringX on String {
int isChannelPageNumber(int max) {
if(this.length < 2 || this[0] != '/') {
return 0;
}
String rest = this.substring(1);
//print("rest = $rest");
int? n = int.tryParse(rest);
if( n != null) {
if( n < max)
return n;
}
return 0;
}
isEnglish( ) {
// since smaller words can be smileys they should not be translated
if( length < 10)
return true;
if( !isLatinAlphabet())
return false;
if (isRomanceLanguage())
return false;
return true;
}
isPortugese() {
false; // https://1000mostcommonwords.com/1000-most-common-portuguese-words/
}
bool isRomanceLanguage() {
// https://www.thoughtco.com/most-common-french-words-1372759
Set<String> frenchWords = {"oui", "je", "le", "un", "de", "merci", "une", "ce", "pas"}; // "et" is in 'et al'
Set<String> spanishWords = {"y", "se", "el", "uso", "que", "te", "los", "va", "ser", "si", "por", "lo", "es", "era", "un", "o"};
Set<String> portugeseWords = {"como", "seu", "que", "ele", "foi", "eles", "tem", "este", "por", "quente", "vai",
"ter", "mas", "ou", "teve", "fora", "é", "te", "mais"};
Set<String> romanceWords = frenchWords.union(spanishWords).union(portugeseWords);
for( String word in romanceWords) {
if( this.toLowerCase().contains(" $word ")) {
return true;
}
}
return false;
}
isLatinAlphabet({caseSensitive = false}) {
int countLatinletters = 0;
for (int i = 0; i < length; i++) {
final target = caseSensitive ? this[i] : this[i].toLowerCase();
if ( (target.codeUnitAt(0) > 96 && target.codeUnitAt(0) < 123) || ( isNumeric(target) ) || isWhitespace(target)) {
countLatinletters++;
}
}
if( countLatinletters < ( 40.0/100 ) * length ) {
return false;
} else {
return true;
}
}
}
bool isValidPubkey(String pubkey) {
if( pubkey.length == 64) {
return true;
}
return false;
}
String myPadRight(String str, int width) {
String newStr = "";
if( str.length < width) {
newStr = str.padRight(width);
} else {
newStr = str.substring(0, width);
}
return newStr;
}
// returns tags as string that can be used to calculate event has. called from EventData constructor
String getStrTagsFromJson(dynamic json) {
String str = "";
int i = 0;
for( dynamic tag in json ) {
if( i != 0) {
str += ",";
}
str += "[";
int j = 0;
for(dynamic element in tag) {
if( j != 0) {
str += ",";
}
str += "\"${element.toString()}\"";
j++;
}
str += "]";
i++;
}
return str;
}
String addEscapeChars(String str) {
String temp = "";
//temp = temp.replaceAll("\\", "\\\\");
temp = str.replaceAll("\"", "\\\"");
return temp.replaceAll("\n", "\\n");
}
String unEscapeChars(String str) {
//print("in unEscape: |$str|");
String temp = str.replaceAll("\"", "\\\"");
//temp = temp.replaceAll("\\\\", "\\");
temp = temp.replaceAll("\n", "\\n");
//print("returning |$temp|\n");
return temp;
}
void printUnderlined(String x) => { stdout.write("$x\n${getNumDashes(x.length)}\n")};
String getNumSpaces(int num) {
String s = "";
for( int i = 0; i < num; i++) {
s += " ";
}
return s;
}
String getNumDashes(int num, [String dashType = "-"]) {
String s = "";
for( int i = 0; i < num; i++) {
s += dashType;
}
return s;
}
List<List<int>> getUrlRanges(String s) {
List<List<int>> urlRanges = [];
String regexp1 = "http[s]*:\/\/[a-zA-Z0-9]+([.a-zA-Z0-9/_\\-\\#\\+=\\&\\?]*)";
RegExp httpRegExp = RegExp(regexp1);
for( var match in httpRegExp.allMatches(s) ) {
List<int> entry = [match.start, match.end];
urlRanges.add(entry);
}
return urlRanges;
}
// returns true if n is in any of the ranges given in list
int isInRange( int n, List<List<int>> ranges ) {
for( int i = 0; i < ranges.length; i++) {
if( n >= ranges[i][0] && n < ranges[i][1]) {
return ranges[i][1];
}
}
return 0;
}

View File

@ -3,12 +3,9 @@ description: A multi-platform nostr client built for terminal/console
version: 0.1.9-beta
homepage: https://github.com/vishalxl/nostr_console
# Release 0.1.9-beta
# used kind 104
# fix for tag related test fail
# default without argument invocation now possible with no pubkey
# fixed issues that made channels act wonky ( not update properly when created)
# Release 0.2.0-beta
# added utils.dart
# reply shortended

View File

@ -52,7 +52,21 @@ void main() {
});
test('createNodeTree_unordered1', () {
/**
137: nostr is not federated is it? this is like a global feed of all nostr freaks?
|id: 1670 , 11:29 PM Aug 5
137: I dont get the technical stuff about relays and things
|id: f3a2 , 11:31 PM Aug 5
137: different clients make sense to me. I can use different clients to
access nostr but is just one giant soup like twitter
|id: dfc5 , 11:32 PM Aug 5
* */
Event exampleEvent1 = Event.fromJson('["EVENT","latest",{"id":"167063f491c41b7b8f79bc74f318e8a8b0a802bf8364b8bb7d19c887d59ec5de","pubkey":"137d948a0eee45e6cd113faaad934fcf17a97de2236c655b70650d4252daa9d3","created_at":1659722388,"kind":1,"tags":[],"content":"nostr is not federated is it? this is like a global feed of all nostr freaks?","sig":"6db0b287015d9529dfbacef91561cb4e32afd6968edd8454867b8482bde01452e17b6f3de69bffcb2d9deba2a52d3c9ff82e04f7b18eb32428daf7eab5fd27c5"}]', "");
Event exampleEvent2 = Event.fromJson('["EVENT","latest",{"id":"f3a267ecbb631012da618de620bc1fe265f6429f412359bf02330b437cf88e67","pubkey":"137d948a0eee45e6cd113faaad934fcf17a97de2236c655b70650d4252daa9d3","created_at":1659722463,"kind":1,"tags":[["e","167063f491c41b7b8f79bc74f318e8a8b0a802bf8364b8bb7d19c887d59ec5de"]],"content":"I dont get the technical stuff about relays and things","sig":"9f68031687214a24862226f291e3baadd956dc14ba9c5c552f8c881a40aacd34feda667ef4e4b09711cd43950eec2d272d5b11bd7636de5f457f38f31eaff398"}]', "");
Event exampleEvent3 = Event.fromJson('["EVENT","latest",{"id":"dfc5765da281c0ad99cb8693fc98c87f0f86ad56042a414f06f19d41c1315fc3","pubkey":"137d948a0eee45e6cd113faaad934fcf17a97de2236c655b70650d4252daa9d3","created_at":1659722537,"kind":1,"tags":[["e","167063f491c41b7b8f79bc74f318e8a8b0a802bf8364b8bb7d19c887d59ec5de"],["e","f3a267ecbb631012da618de620bc1fe265f6429f412359bf02330b437cf88e67"]],"content":"different clients make sense to me. I can use different clients to access nostr but is just one giant soup like twitter","sig":"d4fdc288e3cb95fc5ab46177fc0982d2aaa3b028eef6649f8200500da9c2e9a16c7a0462638afef7635bfea3094ec10901de759a48e362b60cb08f7e6585e02f"}]', "");
@ -60,7 +74,11 @@ void main() {
Set<Event> listEvents = { exampleEvent3, exampleEvent2, exampleEvent1};
Store node = Store.fromEvents(listEvents);
node.printTree(0, DateTime.now().subtract(Duration(days:1000)), selectorTrees_all); // will test for ~1000 days
expect(node.topPosts.length, 1);
expect ( node.topPosts[0].children.length, 1);
expect ( node.topPosts[0].children[0].children.length, 1);
//node.printTree(0, DateTime.now().subtract(Duration(days:1000)), selectorTrees_all); // will test for ~1000 days
});
test('make_paragraph', () {
@ -216,7 +234,7 @@ String expectedResult =
test('url_break2 ', () {
gTextWidth = 92;
print("123456789|123456789|123456789|123456789|123456789|123456789|123456789|123456789|123456789|");
//print("123456789|123456789|123456789|123456789|123456789|123456789|123456789|123456789|123456789|");
List<String> urls = ["https://news.bitcoin.com/former-us-treasury-secretary-larry-summers-compares-ftx-collapse-to-enron-fraud/",
"https://chromium.googlesource.com/chromium/src/net/+/259a070267d5966ba5ce4bbeb0a9c17b854f8000",
" https://i.imgflip.com/71o242.jpg",
@ -226,9 +244,7 @@ String expectedResult =
urls.forEach((url) {
String res = makeParagraphAtDepth(url, 30);
print(url);
print(res);
print("");
//print(url); print(res);print("");
expect( res, url);
});
});