From 2dec7bf62986103f0584caca19ad654bb9b8d087 Mon Sep 17 00:00:00 2001 From: peteyboy Date: Tue, 5 Mar 2024 02:10:53 -0500 Subject: [PATCH 1/7] Fixed add_history to fix history (so it doesn't contain the link you are about to navigate to). Updated README just slightly. --- README.md | 2 +- connex.pl | 48 +++++++++++++++++++++++++++--------------------- 2 files changed, 28 insertions(+), 22 deletions(-) mode change 100644 => 100755 connex.pl diff --git a/README.md b/README.md index cbe62bd..240be87 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ # Connex -A nex browser in perl \ No newline at end of file +A TUI nex browser in perl using Curses diff --git a/connex.pl b/connex.pl old mode 100644 new mode 100755 index 59e5544..3c470f9 --- a/connex.pl +++ b/connex.pl @@ -6,6 +6,8 @@ use warnings; use strict; use Curses::UI; use Net::Telnet; +use URI::Split; + my $HOST_DEFAULT = "nightfall.city"; my $PATHSPEC_DEFAULT = ''; @@ -32,10 +34,10 @@ my $connect = new Net::Telnet (Timeout => 10, my @menu = ( { -label => 'File', -submenu => [ - { -label => 'Go to Link ^G', -value =>\&goto_link_dialog }, - { -label => 'Change Site ^C', -value =>\&goto_site_dialog }, + { -label => 'Go to Link ^G', -value => \&goto_link_dialog }, + { -label => 'Change Site ^C', -value => \&goto_site_dialog }, { -label => 'Back ^B', -value => \&goto_back }, - { -label => 'History ^H', -value => \&history_status_dialog }, + { -label => 'History ^H', -value => "\&history_status_dialog" }, { -label => 'Exit ^Q', -value => \&exit_dialog } ] }, @@ -58,7 +60,7 @@ sub goto_link_dialog() { my $return = $cui->question(-question => "This is [$host/ $pathspec]. Enter destination link:", -answer => $pathspec, - ); + ); navigate($return); } @@ -85,11 +87,12 @@ sub goto_site_dialog() sub goto_back() { my $fetched = fetch_history(); - if($fetched) { + #if($fetched) { $pathspec =$fetched; load($pathspec); update_status_bar(); - } + history_status_dialog(); + #} } @@ -97,26 +100,28 @@ sub goto_back() sub navigate{ my $link = shift; - if ($link){ - if($link ne ''){ + #if ($link){ + # if($link ne ''){ + add_history($pathspec); #add last link to history before going forward! $pathspec = $link; - add_history($pathspec); load($pathspec); - }else { - $pathspec = ''; - } + # }else { + # $pathspec = ''; + # } update_status_bar(); - } + #} - } sub update_status_bar { + my $browser = $win1->getobj("browser"); my $statusbar = $win1->getobj("status"); $statusbar->text("Current site: $host, current link: [$pathspec]"); $statusbar->draw(); + $browser->focus(); + } @@ -139,16 +144,16 @@ sub fetch_history }else{ return($PATHSPEC_DEFAULT); } - history_status_dialog(); - } sub history_status_dialog { if(@history){ + my $browser = $win1->getobj("browser"); + $browser->focus(); my $history_list = join(", ", @history); - my $return = $cui->status(-message => $history_list); + my $return = $cui->status("$history_list"); } } @@ -203,10 +208,10 @@ $cui->set_binding( \&goto_link_dialog , "\cG"); $cui->set_binding( \&goto_back , "\cB"); $cui->set_binding( \&goto_site_dialog , "\cC"); - - +#start up $texteditor->focus(); -load(''); + +navigate(''); $cui->mainloop(); @@ -256,6 +261,7 @@ sub load $ok= $connect->print($pathspec); @lines =$connect->getlines(ErrMode=> 'return'); print $connect->eof(); +#handle non-existant request? die unless $connect->eof(); $connect->close(); my $widget= $texteditor; @@ -265,7 +271,7 @@ sub load foreach $currentline (@lines){ if ($currentline =~ m/^=>/){ $count+=1; - $currentline =~ s/^=>(.*$)/[$count\]$1/; + $currentline =~ s/(^=>.*$)/$1 [\>$count\]/; } $loaded_text= $loaded_text . $currentline; } -- 2.39.5 From e957438be64cffd608f2bbdecf52d97a176c6714 Mon Sep 17 00:00:00 2001 From: peteyboy Date: Wed, 6 Mar 2024 04:09:19 -0500 Subject: [PATCH 2/7] Lots of updates, updated internals to use nex:// urls for navigation and history and links. Fixed history and go back, mostly. Added code to modify links in read index pages only to add "[>#]" to identify link number. Recorded all links on a page in an array and used URI to handle relative links including "../index" type links (I hope, there were none to test). Added UI to navigate by link #s I made, went with kludgy dialog box. Had the idea to use > and < for navigation to copy the '[>#]' format I added to index page link lines, which works not bad. Added some help to status bar, other stuff. What needs to get added is some 'branding' (program name, about dialog) and a help dialog and to reorganize the menu so it's not crazy. Also could remove some of the status dialogs. --- connex.pl | 343 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 235 insertions(+), 108 deletions(-) diff --git a/connex.pl b/connex.pl index 3c470f9..29618fd 100755 --- a/connex.pl +++ b/connex.pl @@ -1,32 +1,40 @@ #!/usr/bin/perl -w - +#connex.pl Nightfall Express (nex://) browser +#TODO: Some branding (status popup on load?, Connex menu item?), About dialog +#TODO: Help dialog use strict; use warnings; use strict; use Curses::UI; use Net::Telnet; -use URI::Split; - +use URI::Split qw(uri_split uri_join); +use URI (); my $HOST_DEFAULT = "nightfall.city"; my $PATHSPEC_DEFAULT = ''; my $PORT_DEFAULT = 1900; -my $PROT_NEX = "nex://"; +my $SCHEME_NEX = "nex"; -my $home_default= $PROT_NEX . $HOST_DEFAULT; +my $home_default= $SCHEME_NEX . $HOST_DEFAULT; my $host = "nightfall.city"; my $port = "1900"; my $pathspec = ""; -my $docname = ""; +my $docname; # = ""; my $doctype = "txt"; my $dot_ext = "."; -my @history; +my $HOME_URL = uri_join($SCHEME_NEX,$HOST_DEFAULT); + +my $full_url = $HOME_URL; + +my @history; +my @page_links; my $statusbar; +my $navwindow; my $win1; my $cui = new Curses::UI( -color_support => 1 ); my $connect = new Net::Telnet (Timeout => 10, @@ -34,10 +42,11 @@ my $connect = new Net::Telnet (Timeout => 10, my @menu = ( { -label => 'File', -submenu => [ - { -label => 'Go to Link ^G', -value => \&goto_link_dialog }, - { -label => 'Change Site ^C', -value => \&goto_site_dialog }, + { -label => 'Go to Link ^G', -value => \&navigate_link_dialog }, + { -label => 'Choose Link >', -value => \&goto_link_dialog }, { -label => 'Back ^B', -value => \&goto_back }, - { -label => 'History ^H', -value => "\&history_status_dialog" }, + { -label => 'History ^H', -value => \&history_status_dialog }, + { -label => 'Page Links ^P', -value => \&page_links_dialog }, { -label => 'Exit ^Q', -value => \&exit_dialog } ] }, @@ -47,8 +56,8 @@ my @menu = ( sub exit_dialog() { my $return = $cui->dialog( - -message => "Really quit?", - -title => "Are you sure?", + -title => "Quit Connex?", + -message => "Are you sure?", -buttons => ['yes', 'no'], ); @@ -56,60 +65,102 @@ sub exit_dialog() exit(0) if $return; } -sub goto_link_dialog() + +sub links_dialog() { - my $return = $cui->question(-question => "This is [$host/ $pathspec]. Enter destination link:", - -answer => $pathspec, - ); - navigate($return); + my $return = $cui->dialog( + -message => page_links_list(), + -title => "Page Links", + -buttons => ['ok'], + + ); + } - -sub goto_site_dialog() +sub unsupported_dialog { + my $scheme = shift; + my $return = $cui->dialog( + -message => "$scheme protocol not supported.", + -title => "Bad Navigation", + -buttons => ['ok'], + + ); - my $return = $cui->question(-question => "This is [$host/ $pathspec]. Visit site:", - -answer => $host, - ); - if ($return){ - my $site = $return; - if($site ne ''){ - $host = $site; - add_history($host); - load($pathspec); - update_status_bar(); - } - history_status_dialog(); +} + +sub navigate_link_dialog() +{ + my $return = $cui->question(-question => "This is [$full_url]. Enter destination link:", + -answer => $full_url, + ); + #if not user canceled then navigate + if($return){ + navigate($return); + update_status_bar(); } } - + + +sub goto_link_dialog() +{ + my $return = $cui->question(-question => "Enter link #:", + ); + #if not canceled, or too big or too small, goto link + if($return){ + my $linkcount = scalar @page_links; + if($return <= $linkcount && $return >0){ + goto_link($return); + update_status_bar(); + }else{ + #$browser->focus(); + my $return1 = $cui->status("there is no link # " . $return); + } + #do nothing on cancel + } +} + + + + sub goto_back() { my $fetched = fetch_history(); #if($fetched) { - $pathspec =$fetched; - load($pathspec); + $full_url =$fetched; + load($full_url,0); #don't move back to top update_status_bar(); history_status_dialog(); - #} + #} } +sub goto_link{ + my $linknum = shift; + my $linkcount = scalar @page_links; + + #my $element=$linknum -1; #offset for array element + #if ($element <= $#page_links){ #such a perlism, this is highest INDEX of array + + if ($linknum <= $linkcount){ #such a perlism, this is highest INDEX of array + navigate($page_links[$linknum-1]); #offset from count to index + }else{ + #my $browser = $win1->getobj("browser"); + #$browser->focus(); + my $return = $cui->status("no link # " . $linknum); + } + +} + + sub navigate{ my $link = shift; - #if ($link){ - # if($link ne ''){ - add_history($pathspec); #add last link to history before going forward! - $pathspec = $link; - load($pathspec); - # }else { - # $pathspec = ''; - # } - update_status_bar(); - #} + add_history($full_url); #add last link to history before going forward! + $full_url = $link; + load($full_url, 1); #new URL go to top of page } @@ -118,7 +169,8 @@ sub update_status_bar { my $browser = $win1->getobj("browser"); my $statusbar = $win1->getobj("status"); - $statusbar->text("Current site: $host, current link: [$pathspec]"); + #$full_url = construct_valid_url($SCHEME_NEX, $host, $pathspec, $docname); + $statusbar->text("$full_url" . " | Press '>' key to enter link #. ctl-g to enter nex URL. '<' to go back."); $statusbar->draw(); $browser->focus(); @@ -129,7 +181,6 @@ sub update_status_bar sub add_history { my $link = shift; - print ("link $link"); push(@history, $link); history_status_dialog(); return; @@ -142,7 +193,7 @@ sub fetch_history $latest = pop(@history); return $latest; }else{ - return($PATHSPEC_DEFAULT); + return($HOME_URL); } } @@ -152,12 +203,43 @@ sub history_status_dialog if(@history){ my $browser = $win1->getobj("browser"); $browser->focus(); - my $history_list = join(", ", @history); - my $return = $cui->status("$history_list"); + my $history_list = join("\n", @history); + my $return = $cui->status("history:\n$history_list"); } } +sub page_links_dialog +{ + if(@page_links){ + my $browser = $win1->getobj("browser"); + $browser->focus(); + #my $link_list = join("\n", @page_links); + my $link_list = page_links_list(); + my $return = $cui->status("links on this page:\n$link_list"); + } +} + + +sub page_links_list +{ + if(@page_links){ + my $browser = $win1->getobj("browser"); + $browser->focus(); + #my $link_list = join("\n", @page_links); + my $link_list=""; + my $link; + my $count=0; + foreach $link (@page_links){ + $count+=1; + $link_list = $link_list . "[$count] $link\n"; + } + return $link_list; + } +} + + + my $menu = $cui->add( 'menu','Menubar', -menu => \@menu, @@ -173,6 +255,9 @@ $win1 = $cui->add( -vscrollbar => 'right', ); + + + my $texteditor = $win1->add("browser", "TextViewer", -text => "Start Page", -border => 1, @@ -195,7 +280,7 @@ $statusbar = $win1->add("status", "TextViewer", -width => -1, -reverse => 1, -paddingspaces => 1, - -text => "Current site: $HOST_DEFAULT, current link: [/]", + -text => "$HOME_URL | Press '>' key to enter link #. ctl-g to enter nex URL. '<' to go back.", ); @@ -204,78 +289,120 @@ $statusbar = $win1->add("status", "TextViewer", #key bindings, should match menu items $cui->set_binding(sub {$menu->focus()}, "\cX"); $cui->set_binding( \&exit_dialog , "\cQ"); -$cui->set_binding( \&goto_link_dialog , "\cG"); +$cui->set_binding( \&navigate_link_dialog , "\cG"); $cui->set_binding( \&goto_back , "\cB"); -$cui->set_binding( \&goto_site_dialog , "\cC"); +$cui->set_binding( \&goto_back , "<"); +$cui->set_binding( \&goto_link_dialog , ">"); +$cui->set_binding(sub { + my $cui = shift; + $cui->layout; + $cui->draw; +}, "\cL"); + + + +# There is no need for the editor widget to loose focus, so +# the "loose-focus" binding is disabled here. This also enables the +# use of the "TAB" key in the editor, which is nice to have. +$texteditor->clear_binding('loose-focus'); #start up -$texteditor->focus(); +#$texteditor->focus(); -navigate(''); +navigate($HOME_URL); $cui->mainloop(); -#pick apart nex:// urls, which we should be using -#sub parse_url #need to pass in url; and host, pathspec, file variables to be filled -#{ -# my $url = @_[0]; -# my $host = url; -# host =~ s/^nex://([a-z0-9]*)\/[a-z0-9\/\.]*$/$1/; -# my $pathspec = url; -# pathspec =~ s/^nex://[a-z0-9]*(\/[a-z0-9\/]*)[[a-z0-9\.]*$)/$1/; -# my $file = $url -# -#} - - #make nex:// urls from parts, relative urls -#sub construct_valid_url #protocol, host, pathspec -#{ -# my $protocol = shift; -# my $host = shift; -# my $pathspec = shift; -# my $file = shift; -# my $url = $protocol; -#need error handling -#what about the end slash and files vs index? -# $url = $protocol . $host; -# if ($pathspec){ -# $url = $url . '/' . $pathspec; -# if ($file){ -# $url = $url . '.' $file; -# } -# } -# return $url; -#} +sub construct_valid_url #scheme, host, pathspec, docname +{ + my $scheme = shift; + my $host = shift; + my $pathspec = shift; + my $docname = shift; + if (defined($docname)){ + $pathspec= $pathspec . '/' . $docname; #this is just local pathspec + } + my $url = uri_join($scheme, $host, $pathspec); + return $url; +} +sub is_path_index{ + my $path = shift; + my $result = 1; + if ($path !~ /\/$/ && $path =~ /\.[a-zA-Z]*$/){ + $result =0; + } + return($result); +} + +sub add_page_link{ + my $linkline = shift; + my $base_url = shift; + my $uri_object; + #my $link= $linkline=~ s/^=>[ ]*(.*$)/$1/r; + local $URI::ABS_ALLOW_RELATIVE_SCHEME = 1; + local $URI::ABS_REMOTE_LEADING_DOTS = 1; + $uri_object=URI->new_abs($linkline=~ /^=>[ ]+([^ ]*)/,$base_url); + + push(@page_links, $uri_object->as_string); + my $count = scalar @page_links; #scalar is size/count of links, but $#page_links is highest INDEX + return $linkline =~ s/(^=>.*$)/$1 [\>$count\]/r; + +} sub load { - my $pathspec = shift; my @lines; my $ok; - $connect->host($host); - $connect->port($port); - $ok= $connect->open($host); - $ok= $connect->print($pathspec); - @lines =$connect->getlines(ErrMode=> 'return'); - print $connect->eof(); -#handle non-existant request? - die unless $connect->eof(); - $connect->close(); - my $widget= $texteditor; - my $loaded_text =""; - my $currentline; - my $count=0; - foreach $currentline (@lines){ - if ($currentline =~ m/^=>/){ - $count+=1; - $currentline =~ s/(^=>.*$)/$1 [\>$count\]/; - } - $loaded_text= $loaded_text . $currentline; - } - $widget->text($loaded_text); + my $url = shift; + my $top = shift; + #my $scheme, $host, $path, $query, $frag; + my ($scheme, $host, $path, $query, $frag) = uri_split($url); + #what happens with different scheme? + if ($scheme eq $SCHEME_NEX){ + $connect->host($host); + $connect->port($port); + $ok= $connect->open($host); + $ok= $connect->print($path); + @lines =$connect->getlines(ErrMode=> 'return'); + print $connect->eof(); + #handle non-existant request? + die unless $connect->eof(); + $connect->close(); + my $widget= $texteditor; + + #loop through nex response and load into text editor. Identify, mark and store link lines for index pages + #TODO: store link lines for index pages + my $page_contents =""; #this is the page contents + my $currentline; + my $count=0; + my $is_index= is_path_index($path); + undef @page_links; #clear list + foreach $currentline (@lines){ + if ($currentline =~ m/^=>/){ + if ($is_index){ + $currentline = add_page_link($currentline, $url); + } + } + $page_contents= $page_contents . $currentline; + } + $widget->text($page_contents); + $widget->draw(); + if ($top){ + $widget->pos(0); + } + }else{ + #can't load non-nex as of now + my $browser = $win1->getobj("browser"); + $browser->focus(); + my $return = unsupported_dialog($scheme); + #pop and trash history + my $fetched = fetch_history(); + + } + } -- 2.39.5 From a7acb6501ed99151e28e632a67270bb2d8dddf80 Mon Sep 17 00:00:00 2001 From: peteyboy Date: Wed, 6 Mar 2024 14:57:09 -0500 Subject: [PATCH 3/7] Added ability to invoke with a starting nex url from command line. Added rudimentary About page Added rudimentary Help page --- connex.pl | 75 +++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 59 insertions(+), 16 deletions(-) diff --git a/connex.pl b/connex.pl index 29618fd..cd5966f 100755 --- a/connex.pl +++ b/connex.pl @@ -16,8 +16,6 @@ my $PATHSPEC_DEFAULT = ''; my $PORT_DEFAULT = 1900; my $SCHEME_NEX = "nex"; -my $home_default= $SCHEME_NEX . $HOST_DEFAULT; - my $host = "nightfall.city"; my $port = "1900"; my $pathspec = ""; @@ -28,7 +26,17 @@ my $dot_ext = "."; my $HOME_URL = uri_join($SCHEME_NEX,$HOST_DEFAULT); -my $full_url = $HOME_URL; +#if argument entered, it should be a nex url: +my $full_url= $ARGV[0]; +if (defined $full_url){ + my $uri=URI->new($full_url, $SCHEME_NEX); + if ($uri->scheme ne $SCHEME_NEX){ + die "need a $SCHEME_NEX url, or start without supplying URL argument.\n"; + } + $full_url= $uri->as_string; +}else{ + $full_url = $HOME_URL; +} my @history; my @page_links; @@ -42,14 +50,20 @@ my $connect = new Net::Telnet (Timeout => 10, my @menu = ( { -label => 'File', -submenu => [ - { -label => 'Go to Link ^G', -value => \&navigate_link_dialog }, - { -label => 'Choose Link >', -value => \&goto_link_dialog }, - { -label => 'Back ^B', -value => \&goto_back }, - { -label => 'History ^H', -value => \&history_status_dialog }, - { -label => 'Page Links ^P', -value => \&page_links_dialog }, - { -label => 'Exit ^Q', -value => \&exit_dialog } + { -label => 'Choose Link >', -value => \&goto_link_dialog }, + { -label => 'Back ^B/<', -value => \&goto_back }, + { -label => 'Go to Link ^G', -value => \&navigate_link_dialog }, + { -label => 'Page Links ^P', -value => \&page_links_dialog }, + { -label => 'History ^Y', -value => \&history_status_dialog }, + { -label => 'Exit ^Q', -value => \&exit_dialog } ] }, + { -label => 'Help', + -submenu => [ + { -label => 'Help ^H', -value => \&help_dialog }, + { -label => 'About ', -value => \&about_dialog }, + ] + }, ); @@ -170,7 +184,7 @@ sub update_status_bar my $browser = $win1->getobj("browser"); my $statusbar = $win1->getobj("status"); #$full_url = construct_valid_url($SCHEME_NEX, $host, $pathspec, $docname); - $statusbar->text("$full_url" . " | Press '>' key to enter link #. ctl-g to enter nex URL. '<' to go back."); + $statusbar->text("$full_url" . " | Press '>' key to enter link #. ctl-x for Menu. '<' to go back."); $statusbar->draw(); $browser->focus(); @@ -238,7 +252,34 @@ sub page_links_list } } +sub about_dialog +{ + my $browser = $win1->getobj("browser"); + $browser->focus(); + my $return = $cui->status("Connex browser\n by gorf\@rawtext.club\n 2024"); +} +sub help_dialog +{ + my $browser = $win1->getobj("browser"); + $browser->focus(); + my $message = <<'END_MESSAGE'; +Navigation: +Press '>' key to select a '[>#]link by # +Press '<' key to go back to previous page + +Program Features: +Press ctl-x for menu +END_MESSAGE + + my $return = $cui->dialog( + -message => $message, + -title => "Connex Help", + -buttons => ['ok'], + + ); + +} my $menu = $cui->add( 'menu','Menubar', @@ -249,6 +290,7 @@ my $menu = $cui->add( $win1 = $cui->add( 'win1', 'Window', + -title => "Connex, a Nightfall Express (nex://) browser", -border => 1, -y => 1, -bfg => 'red', @@ -280,12 +322,10 @@ $statusbar = $win1->add("status", "TextViewer", -width => -1, -reverse => 1, -paddingspaces => 1, - -text => "$HOME_URL | Press '>' key to enter link #. ctl-g to enter nex URL. '<' to go back.", + -text => "$full_url | Press '>' key to enter link #; ctl-x for menu; '<' to go back.", ); - - #key bindings, should match menu items $cui->set_binding(sub {$menu->focus()}, "\cX"); $cui->set_binding( \&exit_dialog , "\cQ"); @@ -293,6 +333,9 @@ $cui->set_binding( \&navigate_link_dialog , "\cG"); $cui->set_binding( \&goto_back , "\cB"); $cui->set_binding( \&goto_back , "<"); $cui->set_binding( \&goto_link_dialog , ">"); +$cui->set_binding( \&page_links_dialog , "\cP"); +$cui->set_binding( \&history_status_dialog , "\cY"); +$cui->set_binding( \&help_dialog , "\cH"); $cui->set_binding(sub { my $cui = shift; $cui->layout; @@ -304,12 +347,12 @@ $cui->set_binding(sub { # There is no need for the editor widget to loose focus, so # the "loose-focus" binding is disabled here. This also enables the # use of the "TAB" key in the editor, which is nice to have. -$texteditor->clear_binding('loose-focus'); +#$texteditor->clear_binding('loose-focus'); #start up -#$texteditor->focus(); +$texteditor->focus(); -navigate($HOME_URL); +navigate($full_url); $cui->mainloop(); -- 2.39.5 From 7de73ed08893708c625581d50d8f1e54a9e7d732 Mon Sep 17 00:00:00 2001 From: peteyboy Date: Fri, 15 Mar 2024 02:30:33 -0400 Subject: [PATCH 4/7] A lot of updates. --- connex.pl | 451 ------------------------------------------------------ 1 file changed, 451 deletions(-) delete mode 100755 connex.pl diff --git a/connex.pl b/connex.pl deleted file mode 100755 index cd5966f..0000000 --- a/connex.pl +++ /dev/null @@ -1,451 +0,0 @@ -#!/usr/bin/perl -w -#connex.pl Nightfall Express (nex://) browser -#TODO: Some branding (status popup on load?, Connex menu item?), About dialog -#TODO: Help dialog - -use strict; -use warnings; -use strict; -use Curses::UI; -use Net::Telnet; -use URI::Split qw(uri_split uri_join); -use URI (); - -my $HOST_DEFAULT = "nightfall.city"; -my $PATHSPEC_DEFAULT = ''; -my $PORT_DEFAULT = 1900; -my $SCHEME_NEX = "nex"; - -my $host = "nightfall.city"; -my $port = "1900"; -my $pathspec = ""; -my $docname; # = ""; -my $doctype = "txt"; -my $dot_ext = "."; - - -my $HOME_URL = uri_join($SCHEME_NEX,$HOST_DEFAULT); - -#if argument entered, it should be a nex url: -my $full_url= $ARGV[0]; -if (defined $full_url){ - my $uri=URI->new($full_url, $SCHEME_NEX); - if ($uri->scheme ne $SCHEME_NEX){ - die "need a $SCHEME_NEX url, or start without supplying URL argument.\n"; - } - $full_url= $uri->as_string; -}else{ - $full_url = $HOME_URL; -} - -my @history; -my @page_links; - -my $statusbar; -my $navwindow; -my $win1; -my $cui = new Curses::UI( -color_support => 1 ); -my $connect = new Net::Telnet (Timeout => 10, - Errmode => 'return'); -my @menu = ( - { -label => 'File', - -submenu => [ - { -label => 'Choose Link >', -value => \&goto_link_dialog }, - { -label => 'Back ^B/<', -value => \&goto_back }, - { -label => 'Go to Link ^G', -value => \&navigate_link_dialog }, - { -label => 'Page Links ^P', -value => \&page_links_dialog }, - { -label => 'History ^Y', -value => \&history_status_dialog }, - { -label => 'Exit ^Q', -value => \&exit_dialog } - ] - }, - { -label => 'Help', - -submenu => [ - { -label => 'Help ^H', -value => \&help_dialog }, - { -label => 'About ', -value => \&about_dialog }, - ] - }, - -); - -sub exit_dialog() -{ - my $return = $cui->dialog( - -title => "Quit Connex?", - -message => "Are you sure?", - -buttons => ['yes', 'no'], - - ); - -exit(0) if $return; -} - - -sub links_dialog() -{ - my $return = $cui->dialog( - -message => page_links_list(), - -title => "Page Links", - -buttons => ['ok'], - - ); - -} - -sub unsupported_dialog -{ - my $scheme = shift; - my $return = $cui->dialog( - -message => "$scheme protocol not supported.", - -title => "Bad Navigation", - -buttons => ['ok'], - - ); - -} - -sub navigate_link_dialog() -{ - my $return = $cui->question(-question => "This is [$full_url]. Enter destination link:", - -answer => $full_url, - ); - #if not user canceled then navigate - if($return){ - navigate($return); - update_status_bar(); - } -} - - -sub goto_link_dialog() -{ - my $return = $cui->question(-question => "Enter link #:", - ); - #if not canceled, or too big or too small, goto link - if($return){ - my $linkcount = scalar @page_links; - if($return <= $linkcount && $return >0){ - goto_link($return); - update_status_bar(); - }else{ - #$browser->focus(); - my $return1 = $cui->status("there is no link # " . $return); - } - #do nothing on cancel - } -} - - - - - -sub goto_back() -{ - my $fetched = fetch_history(); - #if($fetched) { - $full_url =$fetched; - load($full_url,0); #don't move back to top - update_status_bar(); - history_status_dialog(); - #} - -} - - - -sub goto_link{ - my $linknum = shift; - my $linkcount = scalar @page_links; - - #my $element=$linknum -1; #offset for array element - #if ($element <= $#page_links){ #such a perlism, this is highest INDEX of array - - if ($linknum <= $linkcount){ #such a perlism, this is highest INDEX of array - navigate($page_links[$linknum-1]); #offset from count to index - }else{ - #my $browser = $win1->getobj("browser"); - #$browser->focus(); - my $return = $cui->status("no link # " . $linknum); - } - -} - - -sub navigate{ - my $link = shift; - add_history($full_url); #add last link to history before going forward! - $full_url = $link; - load($full_url, 1); #new URL go to top of page - -} - - -sub update_status_bar -{ - my $browser = $win1->getobj("browser"); - my $statusbar = $win1->getobj("status"); - #$full_url = construct_valid_url($SCHEME_NEX, $host, $pathspec, $docname); - $statusbar->text("$full_url" . " | Press '>' key to enter link #. ctl-x for Menu. '<' to go back."); - $statusbar->draw(); - $browser->focus(); - - -} - - -sub add_history -{ - my $link = shift; - push(@history, $link); - history_status_dialog(); - return; -} - -sub fetch_history -{ - my $latest; - if(@history) { - $latest = pop(@history); - return $latest; - }else{ - return($HOME_URL); - } -} - - -sub history_status_dialog -{ - if(@history){ - my $browser = $win1->getobj("browser"); - $browser->focus(); - my $history_list = join("\n", @history); - my $return = $cui->status("history:\n$history_list"); - } -} - - -sub page_links_dialog -{ - if(@page_links){ - my $browser = $win1->getobj("browser"); - $browser->focus(); - #my $link_list = join("\n", @page_links); - my $link_list = page_links_list(); - my $return = $cui->status("links on this page:\n$link_list"); - } -} - - -sub page_links_list -{ - if(@page_links){ - my $browser = $win1->getobj("browser"); - $browser->focus(); - #my $link_list = join("\n", @page_links); - my $link_list=""; - my $link; - my $count=0; - foreach $link (@page_links){ - $count+=1; - $link_list = $link_list . "[$count] $link\n"; - } - return $link_list; - } -} - -sub about_dialog -{ - my $browser = $win1->getobj("browser"); - $browser->focus(); - my $return = $cui->status("Connex browser\n by gorf\@rawtext.club\n 2024"); -} - -sub help_dialog -{ - my $browser = $win1->getobj("browser"); - $browser->focus(); - my $message = <<'END_MESSAGE'; -Navigation: -Press '>' key to select a '[>#]link by # -Press '<' key to go back to previous page - -Program Features: -Press ctl-x for menu -END_MESSAGE - - my $return = $cui->dialog( - -message => $message, - -title => "Connex Help", - -buttons => ['ok'], - - ); - -} - -my $menu = $cui->add( - 'menu','Menubar', - -menu => \@menu, - -fg => "blue", -); - - -$win1 = $cui->add( - 'win1', 'Window', - -title => "Connex, a Nightfall Express (nex://) browser", - -border => 1, - -y => 1, - -bfg => 'red', - -vscrollbar => 'right', - ); - - - - -my $texteditor = $win1->add("browser", "TextViewer", - -text => "Start Page", - -border => 1, - -padtop => 0, - -padbottom => 3, - -showlines => 0, - -sbborder => 0, - -vscrollbar => 1, - -hscrollbar => 1, - -showhardreturns => 0, - -wrapping => 0, # wrapping slows down the editor :-( - ); - - -$statusbar = $win1->add("status", "TextViewer", - -border => 1, - -bfg => 'red', - -y => -1, - -height => 1, - -width => -1, - -reverse => 1, - -paddingspaces => 1, - -text => "$full_url | Press '>' key to enter link #; ctl-x for menu; '<' to go back.", - ); - - -#key bindings, should match menu items -$cui->set_binding(sub {$menu->focus()}, "\cX"); -$cui->set_binding( \&exit_dialog , "\cQ"); -$cui->set_binding( \&navigate_link_dialog , "\cG"); -$cui->set_binding( \&goto_back , "\cB"); -$cui->set_binding( \&goto_back , "<"); -$cui->set_binding( \&goto_link_dialog , ">"); -$cui->set_binding( \&page_links_dialog , "\cP"); -$cui->set_binding( \&history_status_dialog , "\cY"); -$cui->set_binding( \&help_dialog , "\cH"); -$cui->set_binding(sub { - my $cui = shift; - $cui->layout; - $cui->draw; -}, "\cL"); - - - -# There is no need for the editor widget to loose focus, so -# the "loose-focus" binding is disabled here. This also enables the -# use of the "TAB" key in the editor, which is nice to have. -#$texteditor->clear_binding('loose-focus'); - -#start up -$texteditor->focus(); - -navigate($full_url); -$cui->mainloop(); - - -#make nex:// urls from parts, relative urls -sub construct_valid_url #scheme, host, pathspec, docname -{ - my $scheme = shift; - my $host = shift; - my $pathspec = shift; - my $docname = shift; - if (defined($docname)){ - $pathspec= $pathspec . '/' . $docname; #this is just local pathspec - } - my $url = uri_join($scheme, $host, $pathspec); - return $url; -} - -sub is_path_index{ - my $path = shift; - my $result = 1; - if ($path !~ /\/$/ && $path =~ /\.[a-zA-Z]*$/){ - $result =0; - } - return($result); -} - -sub add_page_link{ - my $linkline = shift; - my $base_url = shift; - my $uri_object; - #my $link= $linkline=~ s/^=>[ ]*(.*$)/$1/r; - local $URI::ABS_ALLOW_RELATIVE_SCHEME = 1; - local $URI::ABS_REMOTE_LEADING_DOTS = 1; - $uri_object=URI->new_abs($linkline=~ /^=>[ ]+([^ ]*)/,$base_url); - - push(@page_links, $uri_object->as_string); - my $count = scalar @page_links; #scalar is size/count of links, but $#page_links is highest INDEX - return $linkline =~ s/(^=>.*$)/$1 [\>$count\]/r; - -} - - -sub load -{ - my @lines; - my $ok; - my $url = shift; - my $top = shift; - #my $scheme, $host, $path, $query, $frag; - my ($scheme, $host, $path, $query, $frag) = uri_split($url); - #what happens with different scheme? - if ($scheme eq $SCHEME_NEX){ - $connect->host($host); - $connect->port($port); - $ok= $connect->open($host); - $ok= $connect->print($path); - @lines =$connect->getlines(ErrMode=> 'return'); - print $connect->eof(); - #handle non-existant request? - die unless $connect->eof(); - $connect->close(); - my $widget= $texteditor; - - #loop through nex response and load into text editor. Identify, mark and store link lines for index pages - #TODO: store link lines for index pages - my $page_contents =""; #this is the page contents - my $currentline; - my $count=0; - my $is_index= is_path_index($path); - undef @page_links; #clear list - foreach $currentline (@lines){ - if ($currentline =~ m/^=>/){ - if ($is_index){ - $currentline = add_page_link($currentline, $url); - } - } - $page_contents= $page_contents . $currentline; - } - $widget->text($page_contents); - $widget->draw(); - if ($top){ - $widget->pos(0); - } - }else{ - #can't load non-nex as of now - my $browser = $win1->getobj("browser"); - $browser->focus(); - my $return = unsupported_dialog($scheme); - #pop and trash history - my $fetched = fetch_history(); - - } - - -} - -- 2.39.5 From aa985bdddf245fb2d13a42c0d823dddd6bb8164d Mon Sep 17 00:00:00 2001 From: peteyboy Date: Sun, 24 Mar 2024 22:02:01 +0000 Subject: [PATCH 5/7] updated code to first decent complete version, build module files. Probably want to redo all of this? --- Build.PL | 4 + Changes | 5 + INSTALL | 23 +++ LICENSE | 412 ++++++++++++++++++++++++++++++++++++++ MANIFEST | 28 +++ MANIFEST.SKIP | 11 ++ README | 30 +++ _build_params | 1 + lib/App/Connex.pm | 52 +++++ prereqs.json | 17 ++ script/connex.pl | 492 ++++++++++++++++++++++++++++++++++++++++++++++ 11 files changed, 1075 insertions(+) create mode 100644 Build.PL create mode 100644 Changes create mode 100644 INSTALL create mode 100644 LICENSE create mode 100644 MANIFEST create mode 100644 MANIFEST.SKIP create mode 100644 README create mode 100644 _build_params create mode 100644 lib/App/Connex.pm create mode 100644 prereqs.json create mode 100644 script/connex.pl diff --git a/Build.PL b/Build.PL new file mode 100644 index 0000000..a962e82 --- /dev/null +++ b/Build.PL @@ -0,0 +1,4 @@ +# This Build.PL for App-Connex was generated by mbtiny 0.043. +use 5.008; +use Module::Build::Tiny 0.039; +Build_PL(); diff --git a/Changes b/Changes new file mode 100644 index 0000000..66d9d36 --- /dev/null +++ b/Changes @@ -0,0 +1,5 @@ +Revision history for perl module App::Connex + +0.9 2024-03-07 + + - Created diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..0768ce2 --- /dev/null +++ b/INSTALL @@ -0,0 +1,23 @@ +To install Connex, the NEX:// protocol browser + +* download and set up cpanm, which will help you pull in required libraries: + * curl http://cpanmin.us | perl - -l ~/perl5 App::cpanminus local::lib + * eval `perl -I ~/perl5/lib/perl5 -Mlocal::lib` + * echo 'eval `perl -I ~/perl5/lib/perl5 -Mlocal::lib`' >> ~/.profile + * echo 'export MANPATH=$HOME/perl5/man:$MANPATH' >> ~/.profile + + +* Unzip the package, enter: + * tar xvzf App-Connex-0.9.tar.gz + +* After you have unzipped the package, cd to the package folder App-Connex*, then enter the following commands: +* perl Build.PL +* ./Build +* ./Build test +* ./Build install + +Now run this command to download Perl libraries that the app needs: + ~/perl5/bin/cpanm --installdeps . + +Now you can run with "perl script/connex.pl" + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..404ee52 --- /dev/null +++ b/LICENSE @@ -0,0 +1,412 @@ +This software is copyright (c) 2024 by peteyboy . + +This is free software; you can redistribute it and/or modify it under +the same terms as the Perl 5 programming language system itself. + +Terms of the Perl programming language system itself + +a) the GNU General Public License as published by the Free + Software Foundation; either version 1, or (at your option) any + later version, or +b) the "Artistic License" + +--- The GNU General Public License, Version 1, February 1989 --- + +This software is Copyright (c) 2024 by peteyboy . + +This is free software, licensed under: + + The GNU General Public License, Version 1, February 1989 + + GNU GENERAL PUBLIC LICENSE + Version 1, February 1989 + + Copyright (C) 1989 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The license agreements of most software companies try to keep users +at the mercy of those companies. By contrast, our General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. The +General Public License applies to the Free Software Foundation's +software and to any other program whose authors commit to using it. +You can use it for your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Specifically, the General Public License is designed to make +sure that you have the freedom to give away or sell copies of free +software, that you receive source code or can get it if you want it, +that you can change the software or use pieces of it in new free +programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of a such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must tell them their rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any program or other work which +contains a notice placed by the copyright holder saying it may be +distributed under the terms of this General Public License. The +"Program", below, refers to any such program or work, and a "work based +on the Program" means either the Program or any work containing the +Program or a portion of it, either verbatim or with modifications. Each +licensee is addressed as "you". + + 1. You may copy and distribute verbatim copies of the Program's source +code as you receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice and +disclaimer of warranty; keep intact all the notices that refer to this +General Public License and to the absence of any warranty; and give any +other recipients of the Program a copy of this General Public License +along with the Program. You may charge a fee for the physical act of +transferring a copy. + + 2. You may modify your copy or copies of the Program or any portion of +it, and copy and distribute such modifications under the terms of Paragraph +1 above, provided that you also do the following: + + a) cause the modified files to carry prominent notices stating that + you changed the files and the date of any change; and + + b) cause the whole of any work that you distribute or publish, that + in whole or in part contains the Program or any part thereof, either + with or without modifications, to be licensed at no charge to all + third parties under the terms of this General Public License (except + that you may choose to grant warranty protection to some or all + third parties, at your option). + + c) If the modified program normally reads commands interactively when + run, you must cause it, when started running for such interactive use + in the simplest and most usual way, to print or display an + announcement including an appropriate copyright notice and a notice + that there is no warranty (or else, saying that you provide a + warranty) and that users may redistribute the program under these + conditions, and telling the user how to view a copy of this General + Public License. + + d) You may charge a fee for the physical act of transferring a + copy, and you may at your option offer warranty protection in + exchange for a fee. + +Mere aggregation of another independent work with the Program (or its +derivative) on a volume of a storage or distribution medium does not bring +the other work under the scope of these terms. + + 3. You may copy and distribute the Program (or a portion or derivative of +it, under Paragraph 2) in object code or executable form under the terms of +Paragraphs 1 and 2 above provided that you also do one of the following: + + a) accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of + Paragraphs 1 and 2 above; or, + + b) accompany it with a written offer, valid for at least three + years, to give any third party free (except for a nominal charge + for the cost of distribution) a complete machine-readable copy of the + corresponding source code, to be distributed under the terms of + Paragraphs 1 and 2 above; or, + + c) accompany it with the information you received as to where the + corresponding source code may be obtained. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form alone.) + +Source code for a work means the preferred form of the work for making +modifications to it. For an executable file, complete source code means +all the source code for all modules it contains; but, as a special +exception, it need not include source code for modules which are standard +libraries that accompany the operating system on which the executable +file runs, or for standard header files or definitions files that +accompany that operating system. + + 4. You may not copy, modify, sublicense, distribute or transfer the +Program except as expressly provided under this General Public License. +Any attempt otherwise to copy, modify, sublicense, distribute or transfer +the Program is void, and will automatically terminate your rights to use +the Program under this License. However, parties who have received +copies, or rights to use copies, from you under this General Public +License will not have their licenses terminated so long as such parties +remain in full compliance. + + 5. By copying, distributing or modifying the Program (or any work based +on the Program) you indicate your acceptance of this license to do so, +and all its terms and conditions. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the original +licensor to copy, distribute or modify the Program subject to these +terms and conditions. You may not impose any further restrictions on the +recipients' exercise of the rights granted herein. + + 7. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of the license which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +the license, you may choose any version ever published by the Free Software +Foundation. + + 8. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to humanity, the best way to achieve this is to make it +free software which everyone can redistribute and change under these +terms. + + To do so, attach the following notices to the program. It is safest to +attach them to the start of each source file to most effectively convey +the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19xx name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the +appropriate parts of the General Public License. Of course, the +commands you use may be called something other than `show w' and `show +c'; they could even be mouse-clicks or menu items--whatever suits your +program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + program `Gnomovision' (a program to direct compilers to make passes + at assemblers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +That's all there is to it! + + +--- The Perl Artistic License 1.0 --- + +This software is Copyright (c) 2024 by peteyboy . + +This is free software, licensed under: + + The Perl Artistic License 1.0 + + + + + + The "Artistic License" + + Preamble + +The intent of this document is to state the conditions under which a +Package may be copied, such that the Copyright Holder maintains some +semblance of artistic control over the development of the package, +while giving the users of the package the right to use and distribute +the Package in a more-or-less customary fashion, plus the right to make +reasonable modifications. + +Definitions: + + "Package" refers to the collection of files distributed by the + Copyright Holder, and derivatives of that collection of files + created through textual modification. + + "Standard Version" refers to such a Package if it has not been + modified, or has been modified in accordance with the wishes + of the Copyright Holder as specified below. + + "Copyright Holder" is whoever is named in the copyright or + copyrights for the package. + + "You" is you, if you're thinking about copying or distributing + this Package. + + "Reasonable copying fee" is whatever you can justify on the + basis of media cost, duplication charges, time of people involved, + and so on. (You will not be required to justify it to the + Copyright Holder, but only to the computing community at large + as a market that must bear the fee.) + + "Freely Available" means that no fee is charged for the item + itself, though there may be fees involved in handling the item. + It also means that recipients of the item may redistribute it + under the same conditions they received it. + +1. You may make and give away verbatim copies of the source form of the +Standard Version of this Package without restriction, provided that you +duplicate all of the original copyright notices and associated disclaimers. + +2. You may apply bug fixes, portability fixes and other modifications +derived from the Public Domain or from the Copyright Holder. A Package +modified in such a way shall still be considered the Standard Version. + +3. You may otherwise modify your copy of this Package in any way, provided +that you insert a prominent notice in each changed file stating how and +when you changed that file, and provided that you do at least ONE of the +following: + + a) place your modifications in the Public Domain or otherwise make them + Freely Available, such as by posting said modifications to Usenet or + an equivalent medium, or placing the modifications on a major archive + site such as uunet.uu.net, or by allowing the Copyright Holder to include + your modifications in the Standard Version of the Package. + + b) use the modified Package only within your corporation or organization. + + c) rename any non-standard executables so the names do not conflict + with standard executables, which must also be provided, and provide + a separate manual page for each non-standard executable that clearly + documents how it differs from the Standard Version. + + d) make other distribution arrangements with the Copyright Holder. + +4. You may distribute the programs of this Package in object code or +executable form, provided that you do at least ONE of the following: + + a) distribute a Standard Version of the executables and library files, + together with instructions (in the manual page or equivalent) on where + to get the Standard Version. + + b) accompany the distribution with the machine-readable source of + the Package with your modifications. + + c) give non-standard executables non-standard names, and clearly + document the differences in manual pages (or equivalent), together + with instructions on where to get the Standard Version. + + d) make other distribution arrangements with the Copyright Holder. + +5. You may charge a reasonable copying fee for any distribution of this +Package. You may charge any fee you choose for support of this +Package. You may not charge a fee for this Package itself. However, +you may distribute this Package in aggregate with other (possibly +commercial) programs as part of a larger (possibly commercial) software +distribution provided that you do not advertise this Package as a +product of your own. You may embed this Package's interpreter within +an executable of yours (by linking); this shall be construed as a mere +form of aggregation, provided that the complete Standard Version of the +interpreter is so embedded. + +6. The scripts and library files supplied as input to or produced as +output from the programs of this Package do not automatically fall +under the copyright of this Package, but belong to whoever generated +them, and may be sold commercially, and may be aggregated with this +Package. If such scripts or library files are aggregated with this +Package via the so-called "undump" or "unexec" methods of producing a +binary executable image, then distribution of such an image shall +neither be construed as a distribution of this Package nor shall it +fall under the restrictions of Paragraphs 3 and 4, provided that you do +not represent such an executable image as a Standard Version of this +Package. + +7. C subroutines (or comparably compiled subroutines in other +languages) supplied by you and linked into this Package in order to +emulate subroutines and variables of the language defined by this +Package shall not be considered part of this Package, but are the +equivalent of input as in Paragraph 6, provided these subroutines do +not change the language in any way that would cause it to fail the +regression tests for the language. + +8. Aggregation of this Package with a commercial distribution is always +permitted provided that the use of this Package is embedded; that is, +when no overt attempt is made to make this Package's interfaces visible +to the end user of the commercial distribution. Such use shall not be +construed as a distribution of this Package. + +9. The name of the Copyright Holder may not be used to endorse or promote +products derived from this software without specific prior written permission. + +10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + + The End + diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..ac91216 --- /dev/null +++ b/MANIFEST @@ -0,0 +1,28 @@ +Build +Build.PL +Changes +INSTALL +LICENSE +MANIFEST +MANIFEST.SKIP +META.json +META.yml +MYMETA.json +MYMETA.yml +README +README.md +connex.pl-back +lib/App/Connex.pm +prereqs.json +prototype/nps.sh +prototype/perl +prototype/telnet-test.pl +prototype/telnet-test.pl~ +prototype/test.pl +prototype/test.pl~ +prototype/test.pl~~ +prototype/test2.pl +prototype/test2.pl~ +prototype/url.pl +prototype/url.pl~ +script/connex.pl diff --git a/MANIFEST.SKIP b/MANIFEST.SKIP new file mode 100644 index 0000000..d1a07dd --- /dev/null +++ b/MANIFEST.SKIP @@ -0,0 +1,11 @@ +.git/* +Build.PL-p +Build.PL~ +Changes~ +MANIFEST.SKIP~ +README~ +_build_params +bin/connex.pl~ +connex.pl~ +cpanfile~ +lib/App/Connex.pm~ diff --git a/README b/README new file mode 100644 index 0000000..94eb1de --- /dev/null +++ b/README @@ -0,0 +1,30 @@ +NAME + + App::Connex - Curses UI NEX:// browser + +DESCRIPTION A Curses TUI browser for the Nightfall Express protocol, +nex://. See https://nightfall.city for details, especially +https://nightfall.city/nex/info/specification.txt + +VERSION + + This document describes version 0.9 of App::Connex + +SOURCE + + Source repository is at https://git.sdf.org/peteyboy/Connex =head1 BUGS + + Please report any bugs or feature requests on the gitea issues page + https://git.sdf.org/peteyboy/Connex/issues + +AUTHOR + + peteyboy + +COPYRIGHT AND LICENSE + + This software is copyright (c) 2024, by Pete Dussin, peteyboy@sdf.org + + This is free software; you can redistribute it and/or modify it under + the same terms as the Perl 5 programming language system itself. + diff --git a/_build_params b/_build_params new file mode 100644 index 0000000..8976f1e --- /dev/null +++ b/_build_params @@ -0,0 +1 @@ +[["--install_base","/meta/p/peteyboy/perl5"],[]] \ No newline at end of file diff --git a/lib/App/Connex.pm b/lib/App/Connex.pm new file mode 100644 index 0000000..f69a692 --- /dev/null +++ b/lib/App/Connex.pm @@ -0,0 +1,52 @@ +package App::Connex; + +use FindBin qw($Bin); +use lib "$Bin/../lib"; +use Curses::UI; +use Net::Telnet; +use URI::Split qw(uri_split uri_join); +use URI (); + + +our $VERSION = '0.9'; # VERSION + +1; +# ABSTRACT: A Curses TUI Browser for Nightfall Express NEX:// protocol + +__END__ + +=pod + +=encoding UTF-8 + +=head1 NAME + +App::Connex - Curses UI NEX:// browser + +=head1 DESCRIPTION A Curses TUI browser for the Nightfall Express protocol, nex://. See https://nightfall.city for details, +especially https://nightfall.city/nex/info/specification.txt + +=head1 VERSION + +This document describes version 0.9 of App::Connex + + +=head1 SOURCE + +Source repository is at L +=head1 BUGS + +Please report any bugs or feature requests on the gitea issues page L + +=head1 AUTHOR + +peteyboy + +=head1 COPYRIGHT AND LICENSE + +This software is copyright (c) 2024, by Pete Dussin, peteyboy@sdf.org + +This is free software; you can redistribute it and/or modify it under +the same terms as the Perl 5 programming language system itself. + +=cut diff --git a/prereqs.json b/prereqs.json new file mode 100644 index 0000000..e0c07c9 --- /dev/null +++ b/prereqs.json @@ -0,0 +1,17 @@ +{ + "configure" : { + "requires" : { + "Module::Build::Tiny" : "0.039" + } + }, + "runtime" : { + "requires" : { + "Curses::UI" : "0", + "Net::Telnet" : "0", + "URI" : "0", + "URI::Split" : "0", + "strict" : "0", + "warnings" : "0" + } + } +} diff --git a/script/connex.pl b/script/connex.pl new file mode 100644 index 0000000..23fc067 --- /dev/null +++ b/script/connex.pl @@ -0,0 +1,492 @@ +#!/usr/bin/perl -w +# connex.pl Nightfall Express (nex://) browser +# By Pete Dussin, peteyboy@sdf.org 3/2024 +# This program uses telnet instead of nc to make nex requests, because I couldn't get the Perl nc module to work right. + +#TODO: Some branding (status popup on load?, Connex menu item?), About dialog +#TODO: Fill out help Dialog +#TODO: Fill out About Dialog +#Make status dialog actually useful + + + +use FindBin qw($Bin); +use lib "$Bin/../lib"; +use strict; +use warnings; +use strict; +use Curses::UI; +use Net::Telnet; +use URI::Split qw(uri_split uri_join); +use URI (); +use Term::ReadKey; #for fatpacker? + + + +#=== INITIALIZE VARIABLES === + +#my $HOST_DEFAULT = "nightfall.city"; +my $PATHSPEC_DEFAULT = ''; +my $PORT_DEFAULT = 1900; +my $SCHEME_NEX = "nex"; + +my $host = "nightfall.city"; +my $port = $PORT_DEFAULT; +my $pathspec = $PATHSPEC_DEFAULT; +my $docname; # = ""; + +#for future use, when you think you can deal with doc types +my $doctype = "txt"; +my $dot_ext = "."; + + +#default URL to the "home" NEX site +#my $HOME_URL = uri_join($SCHEME_NEX,$HOST_DEFAULT); +my $HOME_URL = "nex://nightfall.city"; + + + +#==== Command Line Initialization ==== +# Initialize: See if they specified a starting nex URL from command line +#if argument entered, it should be a nex url: +my $full_url= $ARGV[0]; +if (defined $full_url){ + my $uri=URI->new($full_url, $SCHEME_NEX); + if ($uri->scheme ne $SCHEME_NEX){ + die "Need a $SCHEME_NEX url, or start without supplying URL argument.\n"; + } + $full_url= $uri->as_string; +}else{ + $full_url = $HOME_URL; +} + + +#Arrays +my @history; +my @page_links; + + + +#=== UI VARIABLES === +my $statusbar; +my $navwindow; +my $win1; +my $cui = new Curses::UI( -color_support => 1 ); +my $connect = new Net::Telnet (Timeout => 10, + Errmode => 'return'); +my @menu = ( + { -label => 'File', + -submenu => [ + { -label => 'Choose Link >', -value => \&goto_link_dialog }, + { -label => 'Back ^B/<', -value => \&goto_back }, + { -label => 'Go to Link ^G', -value => \&navigate_link_dialog }, + { -label => 'Page Links ^P', -value => \&page_links_dialog }, + { -label => 'History ^Y', -value => \&history_status_dialog }, + { -label => 'Exit ^Q', -value => \&exit_dialog } + ] + }, + { -label => 'Help', + -submenu => [ + { -label => 'Help ^H', -value => \&help_dialog }, + { -label => 'About ', -value => \&about_dialog }, + ] + }, + +); + + +#=== DIALOGS === + +sub exit_dialog() +{ + my $return = $cui->dialog( + -title => "Quit Connex?", + -message => "Are you sure?", + -buttons => ['yes', 'no'], + + ); + +exit(0) if $return; +} + + +sub links_dialog() +{ + my $return = $cui->dialog( + -message => page_links_list(), + -title => "Page Links", + -buttons => ['ok'], + + ); + +} + +sub unsupported_dialog +{ + my $scheme = shift; + my $return = $cui->dialog( + -message => "$scheme protocol not supported.", + -title => "Bad Navigation", + -buttons => ['ok'], + + ); + +} + +sub navigate_link_dialog() +{ + my $return = $cui->question(-question => "This is [$full_url]. Enter destination link:", + -answer => $full_url, + ); + #if not user canceled then navigate + if($return){ + navigate($return); + update_status_bar(); + } +} + + +sub goto_link_dialog() +{ + my $return = $cui->question(-question => "Enter link #:", + ); + #if not canceled, or too big or too small, goto link + if($return){ + my $linkcount = scalar @page_links; + if($return <= $linkcount && $return >0){ + goto_link($return); + update_status_bar(); + }else{ + #$browser->focus(); + my $return1 = $cui->status("there is no link # " . $return); + } + #do nothing on cancel + } +} + + + + +#=== ACTIONS === + +sub goto_back() +{ + my $fetched = fetch_history(); + #if($fetched) { + $full_url =$fetched; + load($full_url,0); #don't move back to top + update_status_bar(); + history_status_dialog(); + #} + +} + + + +sub goto_link{ + my $linknum = shift; + my $linkcount = scalar @page_links; + + #my $element=$linknum -1; #offset for array element + #if ($element <= $#page_links){ #such a perlism, this is highest INDEX of array + + if ($linknum <= $linkcount){ #such a perlism, this is highest INDEX of array + navigate($page_links[$linknum-1]); #offset from count to index + }else{ + #my $browser = $win1->getobj("browser"); + #$browser->focus(); + my $return = $cui->status("no link # " . $linknum); + } + +} + + +sub navigate{ + my $link = shift; + add_history($full_url); #add last link to history before going forward! + $full_url = $link; + load($full_url, 1); #new URL go to top of page + +} + + +sub update_status_bar +{ + my $browser = $win1->getobj("browser"); + my $statusbar = $win1->getobj("status"); + #$full_url = construct_valid_url($SCHEME_NEX, $host, $pathspec, $docname); + $statusbar->text("$full_url" . " | Press '>' key to enter link #. ctl-x for Menu. '<' to go back."); + $statusbar->draw(); + $browser->focus(); + + +} + + +sub add_history +{ + my $link = shift; + push(@history, $link); + history_status_dialog(); + return; +} + +sub fetch_history +{ + my $latest; + if(@history) { + $latest = pop(@history); + return $latest; + }else{ + return($HOME_URL); + } +} + + +sub history_status_dialog +{ + if(@history){ + my $browser = $win1->getobj("browser"); + $browser->focus(); + my $history_list = join("\n", @history); + my $return = $cui->status("history:\n$history_list"); + } +} + + +sub page_links_dialog +{ + if(@page_links){ + my $browser = $win1->getobj("browser"); + $browser->focus(); + #my $link_list = join("\n", @page_links); + my $link_list = page_links_list(); + my $return = $cui->status("links on this page:\n$link_list"); + } +} + + +sub page_links_list +{ + if(@page_links){ + my $browser = $win1->getobj("browser"); + $browser->focus(); + #my $link_list = join("\n", @page_links); + my $link_list=""; + my $link; + my $count=0; + foreach $link (@page_links){ + $count+=1; + $link_list = $link_list . "[$count] $link\n"; + } + return $link_list; + } +} + +sub about_dialog +{ + my $browser = $win1->getobj("browser"); + $browser->focus(); + my $return = $cui->status("Connex browser\n by gorf\@rawtext.club\n 2024"); +} + +sub help_dialog +{ + my $browser = $win1->getobj("browser"); + $browser->focus(); + my $message = <<'END_MESSAGE'; +Navigation: +Press '>' key to select a '[>#]link by # +Press '<' key to go back to previous page + +Program Features: +Press ctl-x for menu +END_MESSAGE + + my $return = $cui->dialog( + -message => $message, + -title => "Connex Help", + -buttons => ['ok'], + + ); + +} + + +#=== KICKOFF UI === + +my $menu = $cui->add( + 'menu','Menubar', + -menu => \@menu, + -fg => "blue", +); + + +$win1 = $cui->add( + 'win1', 'Window', + -title => "Connex, a Nightfall Express (nex://) browser", + -border => 1, + -y => 1, + -bfg => 'red', + -vscrollbar => 'right', + ); + + + + +my $texteditor = $win1->add("browser", "TextViewer", + -text => "Start Page", + -border => 1, + -padtop => 0, + -padbottom => 3, + -showlines => 0, + -sbborder => 0, + -vscrollbar => 1, + -hscrollbar => 1, + -showhardreturns => 0, + -wrapping => 0, # wrapping slows down the editor :-( + ); + + +$statusbar = $win1->add("status", "TextViewer", + -border => 1, + -bfg => 'red', + -y => -1, + -height => 1, + -width => -1, + -reverse => 1, + -paddingspaces => 1, + -text => "$full_url | Press '>' key to enter link #; ctl-x for menu; '<' to go back.", + ); + + +#key bindings, should match menu items +$cui->set_binding(sub {$menu->focus()}, "\cX"); +$cui->set_binding( \&exit_dialog , "\cQ"); +$cui->set_binding( \&navigate_link_dialog , "\cG"); +$cui->set_binding( \&goto_back , "\cB"); +$cui->set_binding( \&goto_back , "<"); +$cui->set_binding( \&goto_link_dialog , ">"); +$cui->set_binding( \&page_links_dialog , "\cP"); +$cui->set_binding( \&history_status_dialog , "\cY"); +$cui->set_binding( \&help_dialog , "\cH"); +$cui->set_binding(sub { + my $cui = shift; + $cui->layout; + $cui->draw; +}, "\cL"); + + + +# There is no need for the editor widget to loose focus, so +# the "loose-focus" binding is disabled here. This also enables the +# use of the "TAB" key in the editor, which is nice to have. +#$texteditor->clear_binding('loose-focus'); + +#=== START UP === +$texteditor->focus(); + +navigate($full_url); +fetch_history(); #navigate places a history entry, will make a duplicate, so remove it +$cui->mainloop(); + + + +#=== NEX STUFF === + +#make nex:// urls from parts, relative urls +sub construct_valid_url #scheme, host, pathspec, docname +{ + my $scheme = shift; + my $host = shift; + my $pathspec = shift; + my $docname = shift; + if (defined($docname)){ + $pathspec= $pathspec . '/' . $docname; #this is just local pathspec + } + my $url = uri_join($scheme, $host, $pathspec); + return $url; +} + +sub is_path_index{ + my $path = shift; + my $result = 1; + if ($path !~ /\/$/ && $path =~ /\.[a-zA-Z]*$/){ + $result =0; + } + return($result); +} + +sub add_page_link{ + my $linkline = shift; + my $base_url = shift; + my $uri_object; + #my $link= $linkline=~ s/^=>[ ]*(.*$)/$1/r; + local $URI::ABS_ALLOW_RELATIVE_SCHEME = 1; + local $URI::ABS_REMOTE_LEADING_DOTS = 1; + $uri_object=URI->new_abs($linkline=~ /^=>[ ]+([^ ]*)/,$base_url); + + push(@page_links, $uri_object->as_string); + my $count = scalar @page_links; #scalar is size/count of links, but $#page_links is highest INDEX + return $linkline =~ s/(^=>.*$)/$1 [\>$count\]/r; + +} + + +#=== NEX REQUESTS AND RESPONSE PROCESSING === +sub load +{ + my @lines; + my $ok; + my $url = shift; + my $top = shift; + #my $scheme, $host, $path, $query, $frag; + my ($scheme, $host, $path, $query, $frag) = uri_split($url); + #what happens with different scheme? + if ($scheme eq $SCHEME_NEX){ + #A lot of trial and error here, connect->print of path was somehow important to get output to complete... + #...also checking the EOF() function + $connect->host($host); + $connect->port($port); + $ok= $connect->open($host); + $ok= $connect->print($path); + @lines =$connect->getlines(ErrMode=> 'return'); + print $connect->eof(); + #TODO:handle non-existant request? Die is not pretty to do here + die unless $connect->eof(); + $connect->close(); + my $widget= $texteditor; + + #loop through nex response and load into text editor. Identify, mark and store link lines for index pages + my $page_contents =""; #this is the page contents to be dumped into the browser widget + my $currentline; + my $count=0; + my $is_index= is_path_index($path); + undef @page_links; #clear list + foreach $currentline (@lines){ + if ($currentline =~ m/^=>/){ + if ($is_index){ + $currentline = add_page_link($currentline, $url); + } + } + $page_contents= $page_contents . $currentline; + } + $widget->text($page_contents); + $widget->draw(); + if ($top){ + $widget->pos(0); + } + }else{ + #can't load non-nex as of now + my $browser = $win1->getobj("browser"); + $browser->focus(); + my $return = unsupported_dialog($scheme); + #pop and revert to history for display + #my $fetched = fetch_history(); + $full_url = fetch_history(); + + } + + +} + -- 2.39.5 From 745ac8605acccf0410618cbeee44e9286736cbaf Mon Sep 17 00:00:00 2001 From: peteyboy Date: Thu, 28 Mar 2024 16:27:07 +0000 Subject: [PATCH 6/7] Added Go Home functionality, revised the status bar to give request status, and moved the current url to be reported in the window (tab) title. --- script/connex.pl | 69 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 58 insertions(+), 11 deletions(-) diff --git a/script/connex.pl b/script/connex.pl index 23fc067..7f54d94 100644 --- a/script/connex.pl +++ b/script/connex.pl @@ -4,9 +4,9 @@ # This program uses telnet instead of nc to make nex requests, because I couldn't get the Perl nc module to work right. #TODO: Some branding (status popup on load?, Connex menu item?), About dialog -#TODO: Fill out help Dialog +#TODO: Fill out help Dialog, mention vi navigatio and search #TODO: Fill out About Dialog -#Make status dialog actually useful +#TODO:Make status dialog actually useful @@ -35,6 +35,13 @@ my $port = $PORT_DEFAULT; my $pathspec = $PATHSPEC_DEFAULT; my $docname; # = ""; + +#new status bar purpose, tracking state +my $S_REQUESTING = "Requesting..."; +my $S_READY= " Ready"; +my $S_DIDNT= "(page not requested) " . $S_READY; +my $S_NORESPONSE ="(No Response) " . $S_READY; + #for future use, when you think you can deal with doc types my $doctype = "txt"; my $dot_ext = "."; @@ -55,7 +62,8 @@ if (defined $full_url){ if ($uri->scheme ne $SCHEME_NEX){ die "Need a $SCHEME_NEX url, or start without supplying URL argument.\n"; } - $full_url= $uri->as_string; + $full_url= $uri->as_string; + $HOME_URL = $full_url; #TODO make sure you want to do this, mostly go home and other defaults will go here instead o nightfall.city }else{ $full_url = $HOME_URL; } @@ -80,7 +88,8 @@ my @menu = ( { -label => 'Choose Link >', -value => \&goto_link_dialog }, { -label => 'Back ^B/<', -value => \&goto_back }, { -label => 'Go to Link ^G', -value => \&navigate_link_dialog }, - { -label => 'Page Links ^P', -value => \&page_links_dialog }, + { -label => 'Go Home ^M', -value => \&goto_home }, + { -label => 'Page Links ^P', -value => \&page_links_dialog }, { -label => 'History ^Y', -value => \&history_status_dialog }, { -label => 'Exit ^Q', -value => \&exit_dialog } ] @@ -141,7 +150,6 @@ sub navigate_link_dialog() #if not user canceled then navigate if($return){ navigate($return); - update_status_bar(); } } @@ -154,8 +162,8 @@ sub goto_link_dialog() if($return){ my $linkcount = scalar @page_links; if($return <= $linkcount && $return >0){ + update_status($S_REQUESTING); goto_link($return); - update_status_bar(); }else{ #$browser->focus(); my $return1 = $cui->status("there is no link # " . $return); @@ -174,14 +182,28 @@ sub goto_back() my $fetched = fetch_history(); #if($fetched) { $full_url =$fetched; + update_status($S_REQUESTING); load($full_url,0); #don't move back to top - update_status_bar(); history_status_dialog(); #} } +#let's consider home to be the first item in the history +sub goto_home() +{ + if(@history) { + $full_url = $history[0]; #peek at first item + }else{ + $full_url=$HOME_URL; + } + update_status($S_REQUESTING); + load($full_url,0); #don't move back to top + history_status_dialog(); + +} + sub goto_link{ my $linknum = shift; @@ -205,23 +227,37 @@ sub navigate{ my $link = shift; add_history($full_url); #add last link to history before going forward! $full_url = $link; - load($full_url, 1); #new URL go to top of page - + update_status($S_REQUESTING); + load($full_url, 1); #new URL go to top of page } sub update_status_bar { + my $status = shift; my $browser = $win1->getobj("browser"); my $statusbar = $win1->getobj("status"); - #$full_url = construct_valid_url($SCHEME_NEX, $host, $pathspec, $docname); - $statusbar->text("$full_url" . " | Press '>' key to enter link #. ctl-x for Menu. '<' to go back."); + $statusbar->text($status . " | Press '>' key to enter link #. ctl-x for Menu. '<' to go back."); $statusbar->draw(); $browser->focus(); +} + +sub update_browser_tab +{ + my $browser = $win1->getobj("browser"); + $browser->title("$full_url"); + $browser->draw(); + } +sub update_status +{ + my $status = shift; + update_status_bar($status); + update_browser_tab(); +} sub add_history { @@ -367,6 +403,7 @@ $cui->set_binding( \&navigate_link_dialog , "\cG"); $cui->set_binding( \&goto_back , "\cB"); $cui->set_binding( \&goto_back , "<"); $cui->set_binding( \&goto_link_dialog , ">"); +$cui->set_binding( \&goto_home , "\cM"); $cui->set_binding( \&page_links_dialog , "\cP"); $cui->set_binding( \&history_status_dialog , "\cY"); $cui->set_binding( \&help_dialog , "\cH"); @@ -442,6 +479,9 @@ sub load my $top = shift; #my $scheme, $host, $path, $query, $frag; my ($scheme, $host, $path, $query, $frag) = uri_split($url); + + + #what happens with different scheme? if ($scheme eq $SCHEME_NEX){ #A lot of trial and error here, connect->print of path was somehow important to get output to complete... @@ -476,6 +516,12 @@ sub load if ($top){ $widget->pos(0); } + if ($page_contents eq ''){ + update_status($S_NORESPONSE); + }else{ + update_status($S_READY); + } + }else{ #can't load non-nex as of now my $browser = $win1->getobj("browser"); @@ -484,6 +530,7 @@ sub load #pop and revert to history for display #my $fetched = fetch_history(); $full_url = fetch_history(); + update_status($S_DIDNT); } -- 2.39.5 From 2a7f8e1ba25abb16872c982c83b29489e64d77ab Mon Sep 17 00:00:00 2001 From: peteyboy Date: Tue, 25 Jun 2024 00:17:33 +0000 Subject: [PATCH 7/7] Made connex.pl runnable is all. --- script/connex.pl | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 script/connex.pl diff --git a/script/connex.pl b/script/connex.pl old mode 100644 new mode 100755 -- 2.39.5