mirror of
https://github.com/vishalxl/nostr_console.git
synced 2025-10-11 11:52:47 +02:00
improved ln qr generation. added --qrln flag
This commit is contained in:
@@ -29,10 +29,11 @@ const String translateArg = "translate";
|
||||
const String colorArg = "color";
|
||||
const String overWriteFlag = "overwrite";
|
||||
const String locationArg = "location";
|
||||
const String lnQrFlag = "qrln";
|
||||
|
||||
Future<void> main(List<String> arguments) async {
|
||||
|
||||
final parser = ArgParser()..addOption(requestArg, abbr: 'q') ..addOption(pubkeyArg, abbr:"p")..addOption(prikeyArg, abbr:"k")
|
||||
final parser = ArgParser()..addOption(requestArg) ..addOption(pubkeyArg, abbr:"p")..addOption(prikeyArg, abbr:"k")
|
||||
..addOption(lastdaysArg, abbr:"d") ..addOption(relayArg, abbr:"r")
|
||||
..addFlag(helpArg, abbr:"h", defaultsTo: false)
|
||||
..addFlag(versionArg, abbr:"v", defaultsTo: false)
|
||||
@@ -44,7 +45,8 @@ Future<void> main(List<String> arguments) async {
|
||||
..addOption(difficultyArg, abbr:"y")
|
||||
..addFlag(overWriteFlag, abbr:"e", defaultsTo: false)
|
||||
..addOption(locationArg, abbr:"l")
|
||||
..addFlag("debug");
|
||||
..addFlag("debug")
|
||||
..addFlag(lnQrFlag, abbr:"q", defaultsTo: false);
|
||||
try {
|
||||
ArgResults argResults = parser.parse(arguments);
|
||||
if( argResults[helpArg]) {
|
||||
@@ -146,6 +148,7 @@ Future<void> main(List<String> arguments) async {
|
||||
gNumLastDays = int.parse(argResults[lastdaysArg]);
|
||||
print("Going to show posts for last $gNumLastDays days");
|
||||
}
|
||||
|
||||
if( argResults[widthArg] != null) {
|
||||
int tempTextWidth = int.parse(argResults[widthArg]);
|
||||
if( tempTextWidth < gMinValidTextWidth ) {
|
||||
@@ -155,8 +158,17 @@ Future<void> main(List<String> arguments) async {
|
||||
print("Going to use $gTextWidth columns for text on screen.");
|
||||
}
|
||||
}
|
||||
try {
|
||||
|
||||
// lnqr will adjust width if needed
|
||||
if( argResults[lnQrFlag] != null) {
|
||||
gShowLnInvoicesAsQr = true;
|
||||
if( gTextWidth < gMinWidthForLnQr) {
|
||||
gTextWidth = gMinWidthForLnQr;
|
||||
}
|
||||
print("Going to show LN invoices as QR code");
|
||||
}
|
||||
|
||||
try {
|
||||
var terminalColumns = gDefaultTextWidth;
|
||||
if( stdout.hasTerminal )
|
||||
terminalColumns = stdout.terminalColumns;
|
||||
@@ -330,7 +342,7 @@ Future<void> main(List<String> arguments) async {
|
||||
stdout.write("...done\n");//received $numUserPosts new posts made by the user\n");
|
||||
|
||||
Set<String> userEvents = getOnlyUserEvents(initialEvents, userPublicKey);
|
||||
print('Total events fetched till now: ${initialEvents.length}. Total user events fetched: ${userEvents.length}');
|
||||
//print('Total events fetched till now: ${initialEvents.length}. Total user events fetched: ${userEvents.length}');
|
||||
|
||||
// get events from channels of user; gets public as well as encrypted channels
|
||||
Set<String> userChannels = getUserChannels(initialEvents, userPublicKey);
|
||||
|
@@ -384,7 +384,9 @@ class EventData {
|
||||
case 1:
|
||||
case 42:
|
||||
evaluatedContent = expandMentions(content, tempChildEventsMap);
|
||||
//evaluatedContent = expandLNInvoices(evaluatedContent);
|
||||
if( gShowLnInvoicesAsQr) {
|
||||
evaluatedContent = expandLNInvoices(evaluatedContent);
|
||||
}
|
||||
if( translator != null && gTranslate && !evaluatedContent.isEnglish()) {
|
||||
if( gDebug > 0) print("found that this comment is non-English: $evaluatedContent");
|
||||
|
||||
|
@@ -175,6 +175,10 @@ int gMenuWidth = 36;
|
||||
int gNameLenDisplayed = 12;
|
||||
String gValidCheckMark = "✔️";
|
||||
|
||||
bool gShowLnInvoicesAsQr = false;
|
||||
int gMinWidthForLnQr = 150;
|
||||
|
||||
|
||||
// https://www.lihaoyi.com/post/BuildyourownCommandLinewithANSIescapecodes.html#8-colors
|
||||
// Color related settings
|
||||
const String defaultTextColor = "green";
|
||||
@@ -297,7 +301,7 @@ usage: $exename [OPTIONS]
|
||||
-r, --relay <relay urls> The comma separated relay urls that are used as main relays. If given, these are used
|
||||
rather than the default relays.
|
||||
-d, --days <N as num> The latest number of days for which events are shown. Default is $gDefaultNumLastDays.
|
||||
-q, --request <REQ string> This request is sent verbatim to the default relay. It can be used to recieve all events
|
||||
--request <REQ string> This request is sent verbatim to the default relay. It can be used to recieve all events
|
||||
from a relay. If not provided, then events for default or given user are shown.
|
||||
-f, --file <filename> Read from given file, if it is present, and at the end of the program execution, write
|
||||
to it all the events (including the ones read, and any new received). Even if not given,
|
||||
|
@@ -414,6 +414,11 @@ class Tree {
|
||||
|
||||
event.printEvent(depth, topPost);
|
||||
|
||||
// sort children by time
|
||||
if( children.length > 1) {
|
||||
children.sort(sortTreeNewestReply);
|
||||
}
|
||||
|
||||
bool leftShifted = false;
|
||||
for( int i = 0; i < children.length; i++) {
|
||||
|
||||
|
@@ -3,6 +3,9 @@ import 'package:qr/qr.dart';
|
||||
|
||||
enum enumRoomType { kind4, kind40, kind140, RoomLocationTag, RoomTTag}
|
||||
|
||||
int gMinLnInvoiceLength = 20; // TODO put real value
|
||||
int gMaxStrLenForQrCode = 600; // in bytes, maximum acceptable length of string that is converted to qr code. for lnbc1 invoices
|
||||
|
||||
String getPostKindFrom(enumRoomType eType) {
|
||||
switch (eType) {
|
||||
case enumRoomType.kind4:
|
||||
@@ -250,44 +253,73 @@ int isInRange( int n, List<List<int>> ranges ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
List<int> getTypeAndModule(String str) {
|
||||
int type = 14, module = 73;
|
||||
// https://jpgraph.net/download/manuals/chunkhtml/ch27.html
|
||||
// both go from 1 to 20 inclusive. index is type.
|
||||
List<int> qrMaxDataBits = [152, 272, 440, 640, 864, 1088, 1248, 1552, 1856, 2192, 2592, 2960, 3424, 3688, 4184, 4712, 5176, 5768, 6360, 6888];
|
||||
List<int> qrModules = [21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, 65, 69, 73, 77, 81, 85, 89, 93, 97];
|
||||
|
||||
if( str.length > 3688 /~ 8) {
|
||||
type = 16;
|
||||
module = 81;
|
||||
// return type and module as entries in a list
|
||||
List<int>? getTypeAndModule(String str) {
|
||||
if( qrMaxDataBits.length != qrModules.length) {
|
||||
//print("ret null 1");
|
||||
return null;
|
||||
}
|
||||
|
||||
// 5 for padding which it seems to need, otherwise it gives error like 'QrInputTooLongException: Input too long. 2212 > 2192' for a str which is exactly 2192
|
||||
int strLen = str.length + 5;
|
||||
for( int i = 0; i < qrModules.length; i++) {
|
||||
//print("checking $strLen, ${strLen * 8} and ${qrMaxDataBits[i]}");
|
||||
if( strLen * 8 <= qrMaxDataBits[i]) {
|
||||
return [i+1, qrModules[i]];
|
||||
}
|
||||
}
|
||||
|
||||
if( str.length > 4712 /~ 8) {
|
||||
type = 18;
|
||||
module = 89;
|
||||
}
|
||||
|
||||
|
||||
return [type, module];
|
||||
//print("ret null 2 strLen = $strLen");
|
||||
return null;
|
||||
}
|
||||
|
||||
int gMaxStrLenForQrCode = 600; // in bytes, maximum acceptable length of string that is converted to qr code. for lnbc1 invoices
|
||||
bool sanityChecked(String lnInvoice) {
|
||||
|
||||
//for( int i = 0 ; i < lnInvoice.length; i++) {
|
||||
//}
|
||||
|
||||
if( lnInvoice.length < gMinLnInvoiceLength)
|
||||
return false;
|
||||
|
||||
if( lnInvoice.substring(0, 4).toLowerCase() != "lnbc")
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
String expandLNInvoices(String content) {
|
||||
|
||||
String regexp1 = '(lnbc1[a-zA-Z0-9]+)';
|
||||
String regexp1 = '(lnbc[a-zA-Z0-9]+)';
|
||||
RegExp httpRegExp = RegExp(regexp1);
|
||||
|
||||
for( var match in httpRegExp.allMatches(content) ) {
|
||||
for( var match in httpRegExp.allMatches(content.toLowerCase()) ) {
|
||||
String lnInvoice = content.substring(match.start, match.end);
|
||||
|
||||
if( !sanityChecked(lnInvoice)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if( lnInvoice.length > gMaxStrLenForQrCode) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
//print(lnInvoice);
|
||||
String qrStr = "";
|
||||
List<int> typeAndModule = getTypeAndModule(lnInvoice);
|
||||
//print(typeAndModule);
|
||||
//print("\nqr code len: ${lnInvoice.length}");
|
||||
|
||||
List<int>? typeAndModule = getTypeAndModule(lnInvoice);
|
||||
if( typeAndModule == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//print("\nqr code len: ${lnInvoice.length}"); print(typeAndModule); print("--");
|
||||
qrStr = getPubkeyAsQrString(lnInvoice, typeAndModule[0], typeAndModule[1], "");
|
||||
//print(qrStr);
|
||||
//print(lnInvoice); print(qrStr);
|
||||
|
||||
content = content.substring(0, match.start) + "\n\n" + qrStr + "\n\n" + content.substring(match.end);
|
||||
}
|
||||
@@ -296,6 +328,7 @@ String expandLNInvoices(String content) {
|
||||
}
|
||||
|
||||
// https://www.sproutqr.com/blog/qr-code-types
|
||||
// https://jpgraph.net/download/manuals/chunkhtml/ch27.html
|
||||
// default 4 and 33 work for pubkey
|
||||
String getPubkeyAsQrString(String str, [int typeNumber = 4, moduleCount = 33, String leftPadding = " "]) {
|
||||
String output = "";
|
||||
|
@@ -1,12 +1,15 @@
|
||||
name: nostr_console
|
||||
description: A multi-platform nostr client built for terminal/console
|
||||
version: 0.3.0-testing
|
||||
version: 0.3.0-beta
|
||||
homepage: https://github.com/vishalxl/nostr_console
|
||||
|
||||
|
||||
# added check marks
|
||||
# 0.3.0
|
||||
# added check marks; added more default users
|
||||
# changed fetch logic: after fetching all friends contacts etc, then reset the relays, and fetched ALL the events in last 2 hours. but not closing connection right now of old relays.
|
||||
# fixed URI exception for NIP05
|
||||
# sorted lists printed in profile ( radixrat)
|
||||
# sorted tree children - now posts get printed in sorted order
|
||||
# --qrln print LNBC invoices as qr code
|
||||
|
||||
#0.2.9
|
||||
# improved fetching logic
|
||||
|
@@ -262,7 +262,7 @@ String expectedResult =
|
||||
expect(3046, node.getNumMessagesInChannel('25e5c82273a271cb1a840d0060391a0bf4965cafeb029d5ab55350b418953fbb'),
|
||||
reason:'verify a public channel has correct number of messages');
|
||||
|
||||
String qrCodeResult1 =
|
||||
String pubkeyQrCodeResult1 =
|
||||
""" █▀▀▀▀▀█ ██▄▄▀ ▄▄ █ ▄▀ █▀▀▀▀▀█
|
||||
█ ███ █ █▄█ ██▄ ▄▄ ██▀▀ █ ███ █
|
||||
█ ▀▀▀ █ ▀ ▀ █▀▄█▄███ ██ █ ▀▀▀ █
|
||||
@@ -282,7 +282,45 @@ String expectedResult =
|
||||
▀▀▀▀▀▀▀ ▀▀▀ ▀▀ ▀ ▀▀ ▀ ▀ \n""";
|
||||
|
||||
String profilePubkey1 = "add06b88bd78c5cbb2cd990e873adfba3eaf8e0217d3208be2be770eb506d430";
|
||||
expect (qrCodeResult1, getPubkeyAsQrString(profilePubkey1), reason: "testing qr code function");
|
||||
expect (pubkeyQrCodeResult1, getPubkeyAsQrString(profilePubkey1), reason: "testing qr code function");
|
||||
|
||||
String lnQrCodeResult1 = """\n\n█▀▀▀▀▀█ █▀▄█▄▄█▀ █ ▄▄ ▀▄ ▀ ▀█▀ ▀▄▀ ██ █▀ ▄█▀███ █▀ ▀▄ █▀▀▀▀▀█
|
||||
█ ███ █ ▄ ▀ ▄▀█▄▄▄▀▀ ▀▀▄▄██▄▄██▄▄█▄▄ ▄▀▄▀ ▀ █████▄▀ █ ███ █
|
||||
█ ▀▀▀ █ ▀▀█▄█▄▄▀▀▀█▀ ▀ █▄█▄██▀▀▀█ ▄▀▀ ███ █▄▄ ▄▀▀▄█▄ ▀ █ ▀▀▀ █
|
||||
▀▀▀▀▀▀▀ █ ▀▄█▄▀ ▀ █ █ █ ▀ ▀ ▀▄█ ▀ █ ▀ ▀ █ ▀▄▀ ▀ ▀ █▄█▄▀ ▀ ▀▀▀▀▀▀▀
|
||||
▄█▀ ██▀█▄▄ █ ▄██▀▀█▄▀▀ ▄ ▄ ██ █▀█▀█▀ █ ▀▀██▄▄█ █▄▀██▀██ ▀█ ▀▄█▀
|
||||
█▄ ▀██▀ █▀ ▄▄▀▄█▀█▀▀ ▀██▄ █▄█ ▄█▄██ ▀▄█▀ ▀█▀▀▀ █ ▄█ ▄▄█▀█▀▄▄▄▄█
|
||||
█ ▄ ▄▀ ▄ ▄▀▀█▄▄▀█▀ █▀▀ █▀██▀▀▄▄▄▄▄▄▄▀▀██▄█▀▀█▀█▄██ █ ▄ █ █▀ █▄▄
|
||||
█▄ ▀▀▀▀██▀▄█ ▄██▀█ █▄█▄▄▄▀ ▀▀▄▀ ▀▀███ ▄█▄▄▄▄▄ ▄ ▄▄ ▀▀▀ ▀▄
|
||||
▀ ▄ ▄▀██▀▄▀ ▀█ ▀█ ▄▄▄█▀ ▄▀▄ ▄▄ ▄█ ▄▀▄▀▀▀▄▄ ▄▀▄▀▀▄▀▀▄ ▄█ ▄██
|
||||
▄█▄▀█▄▀ ██▀ █▀█▄▀█▀▄█▄▀▀███▀█▀▀█▀▀▄█▄▄▀▀█▀▀███▀▄███ ▀ ▀▀▀▀▀ ▀█▀▀█
|
||||
▀ ▀▀▀▀ █ █▀█ ▄▄▄█▀ ▀ █ ▄▀ ▀█▄█▄▄▄█ ▄▀▄█▄ █▀▄▄▀ ▀ ▄█▄▀▄▀▀█▀▄
|
||||
▄ ▄█▄▄▀▀▀▀ █▀▄▀▀ █▀▀▀▄ ▄▀ █▄▄▀█▄▀▀▀▀ ▀▀▀▄██ ▀█▄▀█▄█ ▄▀▄▀█▀ █
|
||||
█▀▄▀▀ ▀▄▄ ▄▄█▄▀▄▄ ▄ ▄▄▄▀ ▄ ▄ █ ▄ ▀▀ █ ▄ █ ▄▄▀ ▄▀ ▄ █▄ ▄█▄
|
||||
▄ ▀▀█▄▀▀██▀ ▀█ ▀ ▄▀▀▀█▀ ▄█▄▀▀▄████▀▄██▄ ▄██▀█▀▀ █ ▀▄ ▀▄▀▀▀ ▄▀
|
||||
█▄██ █▀▀ ▄▄▄ █▀ █▄▄▀ ▄█▄▄▀ ▄█ ██▄ ▄▀▄█▀▄█ █▄▄▄▄ ▄█▀▀▀ █ ▄▄ ▀▄▀▄▀█
|
||||
▀▀▄▀█▀▀▀█ ▄▄▄▄▄▄ █▀▄▄ ▀ ▄ ▄▄█▀▀▀█▀▄█▀█▄ ▄▄▄ ▄█▄█▀▀ █▀▀▀██▀▀█
|
||||
██▀ █ ▀ █ ▄█ ▄██ ▄▀ ▀▀ █ ██ █ ▀ █▀ █▄ ██▄█ ▄▀ ▄▄▄▄▀▄▀█ ▀ ██▄ ▀
|
||||
█▄▀▀█▀▀█▀ ▀ ▄▀ █▄ ▀▄█▀ ▄▄ ▀▀▀▀▀██ █▀▀██ ▀ ▀█▀█▀ ██ ▀█▀▀█ ▄ ▀
|
||||
▀▄▄ ▀█▀█▀ ▀██▄▄█▀▀███▄▀█▀▄██▀▀█▀▀▀▄█▀▄ █▀▀█▀█▀▀███▀▀▀▀▀▀█▀▄███ ▀█
|
||||
▀█▄▀█▄▀ █ ▄▀▀▄▀▄▄█ ▄ █ █ ▀█ ▄▄▄ ▀▄ ▀ ▀█▄ ▄▄▄ ▀ █▀ ▀▄▄▄ █▄█▀
|
||||
█ ▄▄▄ ▀▄▀█▄▀█▀▀█ █ ▄█▄▄▀▀▀▀█▄▄█ ▀ █▀▀▀██ ▄█▄▀▀▄██▀▄█ ▄▀▄▀█▄▀█ ▀█
|
||||
██▄▀▀█▀▄ ▄ █ ▀█ ▄█▄ ▄██ █ ▄ ▄ ▄▄ ▀█ ▄█ ▀▀ ██▄ ▄█▄ ▀▀
|
||||
█▄█▄██▀▀ ▀▀▄█▀ █▀▀██ ▄█▄▀█▄██▀▄█▄▀█▄▀ ▀█▀██▄ █▄▀▄▄▀▀▀██▄ ▀▄█ ██▀
|
||||
█▄▀▄ ▀▀▀ ▄▀▄ ▀ ▀ ▄ ▄▀ ▀██▀▄ █ ▄ █▄▀██▀▄ ▄▄ █▀ ▀▄ █▄▀▄▄ █▀ █ ██ █
|
||||
▄ ▄ █▀█▀▀▄█▀▄▀▀▀███▀ █▀█▄ █▀ ███▀▀▀ ██████▀▀█▀██▀▀█████▄▀▀▀████
|
||||
▀▀▄▀▀▄▀ █▄ ▄█ ▀▄ ▄ ▄▀ ▀ ██▄ █▄ ▄▄▄█▀▄▀ ▄▄▄▄▀█▄█ ▀█ ▀ ██▄
|
||||
▀█▄▄▄█▀▄█ ▀▀█▀█▀▄▀█ █▀▄█▀▀ ▀▄█▀▄█ █▀█ ▀▀ ▄ ▀ ▀█▀▀█ ▀▄ ▀▀▄██▀█▀▄
|
||||
▄ ▀█ ▀▀ ▀ ▀▄ ▄▀ ▀ █▄ ▀ ▀█▄ ▄ █▄▄▄ ▄ █ █▀▄ ▀▄▄▄▄
|
||||
▀▀ ▀ ▀▀▀ ██▄ █▀ ▀▀ █ ▀▄ ██ ██▀▀▀█ ▀ █▄█▀▀▀▀▄ ▀ ▀ ▄▄ █▀▀▀██
|
||||
█▀▀▀▀▀█ █ ▀ ██▄▄▄ ▀▄▄██▄█▄ █ ▀ ██▄ ▀▀ █▀▄█▀ ██ ██▀▄█▄█ ▀ █ █ ▀
|
||||
█ ███ █ ▀▄█▀█▄▀█▀ █▀▀ ▀▀ ▄▀██▀▀███ █ ▄ ▀▄▄▄█▄▄ ▄█ ▄█▀█▀▀▀▀█▀▀
|
||||
█ ▀▀▀ █ █▀██▄▄▄▄▄ ▄█ ▄█ ▄ ██ █▄▄█ █▄▄▄▄▄█ █▀ █▄ ▀ ▀▄▄█ ▄▀▄▄
|
||||
▀▀▀▀▀▀▀ ▀ ▀ ▀ ▀▀▀ ▀ ▀ ▀ ▀▀ ▀ ▀ ▀ ▀▀ ▀ ▀ ▀▀▀ ▀ ▀ ▀▀
|
||||
\n\n""";
|
||||
|
||||
String lnInvoice1 = "lnbc30n1p3689h4sp54ft7dn46clu4h8lyey2zj2hfvp07e2ekcrmceeq4gxmw9ml2pwuspp5zfup7rmneu47f34qznatwcmkexdkl78ppntms9y8vgj75cyzvh5qdq2f38xy6t5wvxqyjw5qcqpjrzjqvhxqvs0ulx0mf5gp6x2vw047capck4pxqnsjv0gg8a4zaegej6gxzadnsqqj3cqqqqqqqqqqqqqqqqqyg9qyysgqv5cg4cly6sr2q4n0vkfcgmgxd5egdrztt8pn4003thqzr8sn5e8swdxw4g75jr233hyr2p655xgwh98jh3pkn3kranjkg0ysrwze44qpqmeq35";
|
||||
expect (expandLNInvoices(lnInvoice1),lnQrCodeResult1, reason: "testing ln qr code function");
|
||||
});
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user