Search code examples
linuxpowershellsshterminalscripting

Ubuntu/Orange Pi5 retrieve open tabs on Chromium (kiosk mode) via terminal - Powershell


I have a problem as of late where I am developing some PowerShell script to manage and update some digital displays. Please see below for my work in progress (By no means done).

I am struggling to be able to output via the terminal or any means (automated text file or via command) active or currently open tabs in Chromium. The idea I am trying to achieve is that if the current tabs correspond to what is required to be opened, to skip a forcing refresh (close and open of Chromium).

##SCRIPT TO RERESH AND MANAGE PI BOXES FOR DISPLAYS##
$getr=$null;

##SET VARIABLES TO GET DATES AND FOR SPECIFIC TIMES IN REGARDS TO UPDATES
$Calendar = Get-Date
$updatestart = Get-Date -Hour 11 -Minute 55
$updatecutoff = Get-Date -Hour 12 -Minute 01

##SET VARIABLES FOR PI INSTRUCTIONS
$exitchrome = "killall -9 chromium-browser &>/dev/null; exit;" ##QUITS BROWSER AND EXITS SCRIPT - HAS TO BE DONE AS CANNOT BE RUN WITH FOLLWOING COMMANDS

Get-Content -Path "C:\temp\ip.txt" | Foreach-Object { ##LOOP THROUGH CONTENTS OF TEXT FILE - IP.TXT
$textfile = $_;

$pos = $textfile.IndexOf("|") ## LOOK FOR PIPE CHARECTER IN TEXT FILE     
$link_string = $textfile.Substring($pos+1) ##CONTENTS AFTER PIPE CHARECTER
$ip = $textfile.Substring(0, $pos) ##CONTENTS BEFORE PIPE CHARECTER
echo $ip

$chrome = "DISPLAY=:0 chromium-browser " + $link_string + " --kiosk --disable-session-crashed-bubble --disable-infobars &> /dev/null &" ##STARTS BROWSER IN KIOSK MODE ON DESKTOP WITH THE DEFINED URLS - ALL ON SCREEN MESSAGES DISABLED

##PLAY CODE##
    $i = 0
    $c = 0
    $w = 1
$wb_chk = "cat -e ~/.config/chromium/Default/Sessions/Tabs_* | sed -e 's/\^@/\n/g' -e '/_\/chrome/d' | grep -Po '(http|https)://\K.*' | sort -u" ##CHECK BROWSER FOR OPEN TABS ASSIGNED TO VARIABLE
$wb_chk_res = ssh orangepi@"$ip" -X "$wb_chk" | Out-String

foreach($url_array in -split $link_string)
{
    $url_array_pos = $url_array.IndexOf("/") ## LOOK FOR CHARECTER RETRUN IN VARIABLE    
    $url_array = $url_array.Substring($url_array_pos+2) ##REMOVE CONTENTS AFTER CHARECTER RETRUN
    $i++

foreach($wbl_chk in -split $wb_chk_res)
{
    $w++
    if ($wbl_chk -eq $url_array) {
    $c++
    }
}
}

echo "$w websites were checked"
echo "There are $c live on the display"
echo "$c websites match the $i URLS in the config file"

##PLAY CODE##

If ($Calendar.Day -eq '28' -AND $Calendar.TimeOfDay -gt $updatestart.TimeOfDay -AND $Calendar.TimeOfDay -lt $updatecutoff.TimeOfDay) { ##IF END OF THE MONTH, RUN UPDATES
ssh -p 222 pi@"$ip" -X "sudo apt-get update; sudo apt-get upgrade -y; sudo reboot;"
Start-Sleep -s 60
}

##CEHCK DISPLAY RES - CANNOT TO GET TO WORK AS A FUCNTION...
$getr = ssh orangepi@"$ip" -X "xrandr -display :0.0;" | Out-String
$res_pos = $getr.IndexOf(",") ## LOOK FOR COMMA CHARECTER IN VARIABLE    
$getr = $getr.Substring($res_pos+2) ##REMOVE CONTENTS AFTER COMMA CHARECTER
$res_pos = $getr.IndexOf(",") ## LOOK FOR COMMA CHARECTER IN VARIABLE    
$getr = $getr.Substring(0, $res_pos) ##REMOVE CONTENTS BEFORE COMMA CHARECTER
$res_pos = $getr.IndexOf(" ") ## LOOK FOR CHARECTER RETRUN IN VARIABLE    
$getr = $getr.Substring($res_pos+1) ##REMOVE CONTENTS AFTER CHARECTER RETRUN

$uptime = ssh orangepi@"$ip" -X "awk '{print $1}' /proc/uptime" | Out-String
$up_pos = $uptime.IndexOf(" ") ## LOOK FOR CHARECTER RETRUN IN VARIABLE    
$uptime = $uptime.Substring(0,$up_pos) ##CONTENTS AFTER CHARECTER RETRUN
echo $uptime
echo $getr

if ($uptime -lt "1800.00" -Or $getr -ne "1920 x 1080") {
echo "Forcing Display Resolution";
ssh orangepi@"$ip" -X "sudo service lightdm restart;"
Start-Sleep -s 10;
ssh orangepi@"$ip" -X "$chrome";
Start-Sleep -s 10;
ssh orangepi@"$ip" -X "$exitchrome";
Start-Sleep -s 10;
$getr=$null;
}

$MATICS = select-string -pattern "xxx.my.leadermes.com" -InputObject $link_string ##LOOK FOR MATICS URL FOR SYNTHEIC MOUSE CLICKS
if ($MATICS -ne $null)
{
$getr = ssh orangepi@"$ip" -X "xrandr -display :0.0;" | Out-String
$res_pos = $getr.IndexOf(",") ## LOOK FOR COMMA CHARECTER IN VARIABLE    
$getr = $getr.Substring($res_pos+2) ##CONTENTS AFTER COMMA CHARECTER
$res_pos = $getr.IndexOf(",") ## LOOK FOR COMMA CHARECTER IN VARIABLE    
$getr = $getr.Substring(0, $res_pos) ##CONTENTS BEFORE COMMA CHARECTER
$res_pos = $getr.IndexOf(" ") ## LOOK FOR CHARECTER RETRUN IN VARIABLE    
$getr = $getr.Substring($res_pos+1) ##CONTENTS AFTER CHARECTER RETRUN
echo "MATICS ON DISPLAY";
ssh orangepi@"$ip" -X "$exitchrome";
ssh orangepi@"$ip" -X "$chrome";

if ($getr -eq "1920 x 1080") {
echo "$getr live";
Start-Sleep -s 15
ssh orangepi@"$ip" -X "DISPLAY=:0 xdotool key Return; exit;"
Start-Sleep -s 20
ssh orangepi@"$ip" -X "DISPLAY=:0 xdotool key Tab Tab space mousemove 220 60 click 1; exit;"
Start-Sleep -s 20
ssh orangepi@"$ip" -X "DISPLAY=:0 xdotool mousemove 1860 180 click 1 mousemove 1920 1080; exit;"
$getr=$null;
}
}

else
{
echo "MATICS IS NOT ON THIS DISPLAY";
ssh orangepi@"$ip" -X "$exitchrome";
ssh orangepi@"$ip" -X "$chrome";
}
}

I have tried BroTab but unable to get that to work at all, appears to be a problem with Ubuntu and Chromium. Is anyone aware of anything that will work to this affect?

I have been able to get working the history of active tabs opened but this only updates on when the browser is manually opened rather than opened via terminal.

The script needs work and error logging/email notifications when there is a failure so the screen can be investigated physically. The first step is to just get this working... which it does just ugly when it refreshes every 30mins - I would rather this just act as a keep alive. I know it requires work and as such open to recommendations on all the code. I will also make use of functions but have also struggled to get these to work as I would like...

I look forward to your suggestions.


Solution

  • I think I have the answer again to my own question... AS much as I looked there is no way to gain a quick access to open URL's in Chrome or other web browsers... as could be seen as a security risk.

    My work around was to loop through every Open Window (thank fully, just Chrome but this could be ruled out too in code) and loop through the tabs to get them one at a time. The command wmctrl -l helped me achieve this.

    I still suspect there might be a better way but this is the way we are going for now.

    The code is still a working progress and looks like the following:

    Clear-Host
    ## SCRIPT TO RERESH AND MANAGE PI BOXES FOR DISPLAYS##
    $getr=$null;
    ## SET VARIABLES TO GET DATES AND FOR SPECIFIC TIMES IN REGARDS TO UPDATES
    $Calendar = Get-Date;
    $updatestart = Get-Date -Hour 11 -Minute 55;
    $updatecutoff = Get-Date -Hour 12 -Minute 01;
    ## SET VARIABLES FOR PI INSTRUCTIONS
    $exitchrome = "killall -9 chromium-browser &>/dev/null; exit;" ## QUITS BROWSER AND EXITS SCRIPT - HAS TO BE DONE AS CANNOT BE RUN WITH FOLLWOING COMMANDS
    Get-Content -Path "C:\Users\xxxx\Documents\DigitalDisplays\display-config.txt" | Foreach-Object { ## START OF LOOP THROUGH CONTENTS OF TEXT FILE - IP.TXT - THIS WILL LOOP THROUGH EVERY IP ADDRESS (SCREEN) ON FILE. 
        $urlcount = 0;
        $url_match_tc = 0;
        $url_match_tf = 0;
        $textfile = $_;
        $chrome = $null;
        $chk_b_string = $null;
        $chk_b_array_string = $null;
        $w=1;
        $no_keywordc = 0;
        $web_c = 0;
        $iic = 0;
        $ffc = 0;
        $browser_off = 0;
        $pos = $textfile.IndexOf("|"); ## LOOK FOR PIPE CHARECTER IN TEXT FILE     
        $link_string = $textfile.Substring($pos+1); ## CONTENTS AFTER PIPE CHARECTER
        $ip = $textfile.Substring(0, $pos) ## CONTENTS BEFORE PIPE CHARECTER
            echo "Checking Screen - $ip";
        $chrome = "DISPLAY=:0 chromium-browser " + $link_string + " --kiosk --disable-session-crashed-bubble --disable-infobars &> /dev/null &"; ##S TARTS BROWSER IN KIOSK MODE ON DESKTOP WITH THE DEFINED URLS - ALL ON SCREEN MESSAGES DISABLED
    ## UPDATES SECTION ##
            If ($Calendar.Day -eq '28' -AND $Calendar.TimeOfDay -gt $updatestart.TimeOfDay -AND $Calendar.TimeOfDay -lt $updatecutoff.TimeOfDay) { ## IF END OF THE MONTH, RUN UPDATES
                ssh -p 222 pi@"$ip" -X "sudo nohup apt-get update; sudo nohup apt-get upgrade -y; sudo nohup reboot;" ## NOHUP MEANS NO DISPLAY
                Start-Sleep -s 300;
            }
    ## END OF UPDATES SECTION##
    ## FIRST CHECK OF UPTIME AND SCREEN RESOLUTION##
    ## CHECK DISPLAY RES - CANNOT TO GET TO WORK AS A FUCNTION...
            $getr = ssh orangepi@"$ip" -X "xrandr -display :0.0;" | Out-String;
            $res_pos = $getr.IndexOf(","); ## LOOK FOR COMMA CHARECTER IN VARIABLE    
            $getr = $getr.Substring($res_pos+2); ## REMOVE CONTENTS AFTER COMMA CHARECTER
            $res_pos = $getr.IndexOf(","); ## LOOK FOR COMMA CHARECTER IN VARIABLE    
            $getr = $getr.Substring(0, $res_pos); ## REMOVE CONTENTS BEFORE COMMA CHARECTER
            $res_pos = $getr.IndexOf(" "); ## LOOK FOR CHARECTER RETRUN IN VARIABLE    
            $getr = $getr.Substring($res_pos+1); ## REMOVE CONTENTS AFTER CHARECTER RETRUN
            $uptime = ssh orangepi@"$ip" -X "awk '{print $1}' /proc/uptime" | Out-String;
            $up_pos = $uptime.IndexOf(" "); ## LOOK FOR CHARECTER RETRUN IN VARIABLE    
            $uptime = $uptime.Substring(0,$up_pos); ## CONTENTS AFTER CHARECTER RETRUN
            $uptime = [int]$uptime;
            $ts = [timespan]::fromseconds($uptime).tostring();
                echo "Uptime = $ts";
                echo "Screen Resolution = $getr";
            if ([int]$uptime -lt 1800.00 -Or $getr -ne "1920 x 1080") {##CHECK SCREEN RESOLUTION AND UPTIME
                    echo "Resetting Display Resolution as just started up or not Default Resolution";
                ##ssh orangepi@"$ip" -X "sudo service lightdm restart;"
                ##Start-Sleep -s 10;
                ##ssh orangepi@"$ip" -X "$chrome";
                ##Start-Sleep -s 10;
                ##ssh orangepi@"$ip" -X "$exitchrome";
                ##Start-Sleep -s 10;
                $getr=$null;
            }
    ## ***END*** FIRST CHECK OF UPTIME AND SCREEN RESOLUTION ***END*** ##
    ## BROWSER CHECK SECTION ##
            $chrome_check_open = ssh orangepi@"$ip" -X "DISPLAY=:0 wmctrl -l" | Out-String;
            $chrome_check = $chrome_check_open.Contains("Chromium");
            if ($chrome_check -eq 0) {
                $host.UI.RawUI.ForegroundColor = "Red";
                    echo "BROWSER IS NOT OPEN!";
                $browser_off = 1;
                $host.UI.RawUI.ForegroundColor = "White";
            } else {
                    echo "BROWSER CHECKING RUNNING NOW";
    ## CODE TO LOOK THROUGH OPEN TABS - LOOPS THROUGH TABS DEPENINDING ON HOW MANY URL's IN CONFIG FILE
            foreach($url_array in -split $link_string) { ## Counts the URL's in the IP/Config text file
                $urlcount++;
            }
            foreach($url2_array in -split $link_string) {
                if ($w -lt $urlcount) { ## SIMPLE COUNT TO CHECK AGAINST SITES IN THE CONFIG TXT FILE - IF LESS THAN WHAT IS THE CONFIG FILE DO BELOW AND ON FINAL ONE DO FINAL CHECK
                    $chk_b_open = ssh orangepi@"$ip" -X "DISPLAY=:0 wmctrl -l" | Out-String; ## THIS GET THE OPEN WINDOW HEADERS - THE LAST ONE IS CHROMIUM
                    $chk_b_open = ([regex]::Matches($chk_b_open,'.','RightToLeft') | ForEach {$_.value}) -join '' | Out-String; ##EASIEST TO FLIP THE STRING BACK TO FRONT
                    $chk_b_pos = $chk_b_open.IndexOf("0"); ## LOOK FOR ZERO CHARECTER IN VARIABLE - BEST IDENTIFIABLE CHARECTER IN THIS SET    
                    $chk_b_open = $chk_b_open.Substring(0,$chk_b_pos) ## CONTENTS BEFORE ZERO CHARECTER
                    $chk_b_open = ([regex]::Matches($chk_b_open,'.','RightToLeft') | ForEach {$_.value}) -join '' | Out-String; ##RETURN STRING TO PROPER ORIENTATION
                    $chk_b_string = $chk_b_open.substring(1); ## TIDYING STRING TO RID OF FIRST BLANK CHARECTER
                    $chk_b_string = $chk_b_string.replace(' ','-'); ## THERE ARE BLANK SPACES IN THE STRING SO WE REPLACE THOSE WITH "-"
                    $chk_b_array_string = "$chk_b_array_string $chk_b_string"; ## BUILDS ARRAY OF ALL OPEN TABS TO CHECK AGAINST LATER
                    ssh orangepi@"$ip" -X "DISPLAY=:0 xdotool keydown ctrl key 0xff09 keyup ctrl"; ## ROTATES TAB TO NEXT
                    $w++; ## INCREASES BY ONE ON PROGRESS OF PREDICTED OPEN TABS
                    Start-Sleep -s 0.5;
                } else { ## SAME AS ABOVE BUT THE FINAL CHECK - THIS IS DEPICTED BY THE NO INCREASE VARIABLE $W AND THE SLEEP DURATION OF HALF A SECOND
                    $chk_b_open = ssh orangepi@"$ip" -X "DISPLAY=:0 wmctrl -l" | Out-String;
                    $chk_b_open = ([regex]::Matches($chk_b_open,'.','RightToLeft') | ForEach {$_.value}) -join '' | Out-String;
                    $chk_b_pos = $chk_b_open.IndexOf("0"); ## LOOK FOR ZERO CHARECTER IN VARIABLE - BEST IDENTIFIABLE CHARECTER IN THIS SET   
                    $chk_b_open = $chk_b_open.Substring(0,$chk_b_pos); ## CONTENTS BEFORE ZERO CHARECTER
                    $chk_b_open = ([regex]::Matches($chk_b_open,'.','RightToLeft') | ForEach {$_.value}) -join '' | Out-String;
                    $chk_b_string = $chk_b_open.substring(1);
                    $chk_b_string = $chk_b_string.replace(' ','-');
                    $chk_b_array_string = "$chk_b_array_string $chk_b_string";
                    ssh orangepi@"$ip" -X "DISPLAY=:0 xdotool keydown ctrl key 0xff09 keyup ctrl";
                }
            }
    ## THIS SHOULD LEAVE US NOW WITH A FULL LIST ARRAY OF ALL OPEN TABS THAT WE CAN CHCK AGAINST
    ## THE ABOVE COULD BE SIMPLIFIED WITH THE USE OF FUNCTIONS IN THE FUTURE TO REDUCE CODE LENGTH
    ## ***END*** CODE TO LOOK THROUGH OPEN TABS - LOOPS THROUGH TABS DEPENINDING ON HOW MANY URL's IN CONFIG FILE ***END*** ##
    ## CHECK CONFIG FILE, AGAINST OPEN TABS USING THE KEYWORD FROM A URL DIRECTORY LIST ##
            foreach($url3_array in -split $link_string) { ## STARTS A NEW ARRAY OF PULLING URLS FROM THE CONFIG FILE
                $keyword = $null;## RESETS THE KEYWORD VARIABLE AT THE START OF THE NEXT WEBSITE IN THE CONFIG
                $no_keyword = 0;
                $ii = 0;
                $ff = 0;
                $web_c++;
                Get-Content -Path "C:\Users\xxxx\Documents\DigitalDisplays\header-ident.txt" | Foreach-Object { ## START ARRAY FROM THE HEADER IDENTITY DIRECTORY
    ## THIS IS ANNOYING AS YOU NEED A STATIC IDENTIFIER FOR EACH WEBSITE AND IF ONE IS NOT LISTED IT WILL WORK AS I HAVE PROGRAMMED TO DO SO BUT WILL ALWAYS REFRESH WHICH IN TURN WILL TAKE LONGER
                    $headerfile = $_;
                    $ident_match = $headerfile.Contains($url3_array); ## THIS MATCHES THE URL BEING CHECKED AGAINST THE KEYWORD LIST (ALSO LISTS URL)
                    if ($ident_match -eq 1) {
                        $chk_ident_pos = $headerfile.IndexOf("|"); ## LOOK FOR PIPE CHARECTER IN VARIABLE
                        $keyword = $headerfile.Substring($chk_ident_pos+1); ## CONTENTS BEFORE PIPE CHARECTER - THIS IDENTIFIES THE KEYWORD WE WILL NBEED TO USE FOR THIS WEBSITE
                    }
                }
                if (!$keyword) { ## IF KEYWORD IS EMPTY OR NO MATCH IS RETURNED - SKIP AND INCREASE VARIABLE TO IDENTIFY THESE
                    $ff++;
                    $no_keyword++;
                    $host.UI.RawUI.ForegroundColor = "Red"; ## TURNS TEXT RED BECUASE THERE IS NO KEYWORD
                        echo "  There is no Keyword listed for $url3_array, please add one - the Screen will refresh until this is added";
                    $host.UI.RawUI.ForegroundColor = "White"; ## RETURNS FONT BACK
                } else {
                    $host.UI.RawUI.ForegroundColor = "Green"; ## TURNS TEXT GREEN AS KEYWORD
                    $host.UI.RawUI.ForegroundColor = "White"; ## RETURNS FONT BACK
                    foreach($c_url_array in -split $chk_b_array_string) { ## FINAL ARRAY TO GET OPEN WINDOW ARRAY SET IN THE SECTION CODE ABOVE (CODE TO LOOK THROUGH OPEN TABS - LOOPS THROUGH TABS DEPENINDING ON HOW MANY URL's IN CONFIG FILE)
                        $keyword_match = $c_url_array.Contains($keyword); ## MATCHES THE KEYWORD
                        if ($keyword_match -eq 1) { ## IF MATCH IS FOUND - INCREASE COUNT $ii AND IF ALREADY EXISISTS (DUPLICATES) FORCE THAT VALUE TO BE 1 - THIS MUST REMAIN 1 AS THERE WAS A MATCH
                            $ii++;
                            if ($ii -gt 0) {
                                $ii = 1;
                            }
                        } else {
                            $ff++; ## IF THERE WAS NOT A MATCH INCREASE THE $ff VARIABLE BY ONE AND AGAIN FORCE THAT ONLY TO BE 1
                            if ($ff -gt 0) {
                                $ff = 1;
                            }
                        }
                    }
                }
                if ($ii -gt 0) { ## IF THERE WAS A MATCH AFTER ALL CHECK HAVE BEEN DONE AGAINST OPEN WINDOWS THEN WE NEED TO RESET $ff  VARILABLE TO 0 AS THIS WAS NO IMPORTANT
                    $ff = 0;
                }
                $iic = $iic + $ii; ## ADD ALL SUCCESSFUL MATCHES TOGETHER
                $ffc = $ffc + $ff; ## ADD ALL SITES NOT LIVE TOGETHER
                $no_keywordc = $no_keywordc + $no_keyword; ## COUNT NO KEYWORDS TOGETHER
            }
                echo "";
                echo "  There are $urlcount sites in the Config File";
                echo "  There are $iic sites that Match Live Tabs";
                echo "  There are $ffc sites in the config file that don't match Live Tabs";
                echo "  There are $no_keywordc site(s) that don't have a Keyword";
    ## ***END*** CHECK CONFIG FILE, AGAINST OPEN TABS USING THE KEYWORD FROM A URL DIRECTORY LIST ***END*** ##
            }
    ## ***END*** WEB BROWSER CHECKING SECTION AND WEBSITES OPEN ***END***##
            if ($iic -lt $urlcount -or $iic -gt $urlcount -or $no_keywordc -gt 0 -or $browser_off -eq 1) { ## IF LIVE MATCHES IS LESS OR GREATER THAN CONFIG URL's, NO KEYWORD OR THE BROWSER WAS OFF - RESET THE DISPLAY
                    echo "";
                    echo "Refreshing screen as there was a website discrepancy, no keyword, the browser was closed or the device was recently powered on";
                    echo "";
                $MATICS = select-string -pattern "xxx.my.leadermes.com" -InputObject $link_string; ## LOOK FOR MATICS URL FOR SYNTHEIC MOUSE CLICKS
                if ($MATICS -ne $null) {
                    ##$getr = ssh orangepi@"$ip" -X "xrandr -display :0.0;" | Out-String;
                    ##$res_pos = $getr.IndexOf(","); ## LOOK FOR COMMA CHARECTER IN VARIABLE    
                    ##$getr = $getr.Substring($res_pos+2); ## CONTENTS AFTER COMMA CHARECTER
                    ##$res_pos = $getr.IndexOf(","); ## LOOK FOR COMMA CHARECTER IN VARIABLE    
                    ##$getr = $getr.Substring(0, $res_pos); ## CONTENTS BEFORE COMMA CHARECTER
                    ##$res_pos = $getr.IndexOf(" "); ## LOOK FOR CHARECTER RETRUN IN VARIABLE    
                    ##$getr = $getr.Substring($res_pos+1); ## CONTENTS AFTER CHARECTER RETRUN
                    ##ssh orangepi@"$ip" -X "$exitchrome";
                    ##ssh orangepi@"$ip" -X "$chrome";
                    if ($getr -eq "1920 x 1080") { ## THIS ALLOW US TO DO DIFFERENT SCREEN RESOLUTIONS IN THE FUTURE IF WE WANT TO
                        ##Start-Sleep -s 25;
                        ##ssh orangepi@"$ip" -X "DISPLAY=:0 xdotool key Return; exit;";
                        ##Start-Sleep -s 20;
                        ##ssh orangepi@"$ip" -X "DISPLAY=:0 xdotool key Tab Tab space mousemove 220 60 click 1; exit;";
                        ##Start-Sleep -s 20;
                        ##ssh orangepi@"$ip" -X "DISPLAY=:0 xdotool mousemove 1860 180 click 1 mousemove 1920 1080; exit;";
                        $getr=$null;
                    }
                } else {
                    ##ssh orangepi@"$ip" -X "$exitchrome";
                    ##ssh orangepi@"$ip" -X "$chrome";
                }
    
            } else {
            echo "";
            echo "No refresh required";
            echo "";
            }
    }
    ## END OF SCRIPT ##