[    [    [    [    [    [    [    b l o g g i n   s p a c e    wiki   ]    ]    ]    ]    ]    ]    ]

Difference between revisions of "Termux"

From blogginpedia
Jump to navigation Jump to search
Line 257: Line 257:
<hr style="border-top: .5px solid #ff69b4; background: transparent;">
<hr style="border-top: .5px solid #ff69b4; background: transparent;">


'''irc_client_advanced.py'''
See [[Termux IRC Client]] as all the code was moved there and will be updated more than this article.
 
<poem>
<small><small>
 
import socket
import ssl
import threading
import sys
import time
import queue
from datetime import datetime
 
class IRCClient:
    def __init__(self):
        self.server = "irc.rizon.net"
        self.port = 6697  # SSL port for Rizon
        self.channels = ["#/g/tv", "#/sp/"]  # Default channels to join
        self.active_channel = self.channels[0] if self.channels else None  # Default active channel
        self.nickname = "LullSac"
        self.realname = "Termux IRC Client"
        self.irc = None
        self.context = ssl.create_default_context()
        self.running = True
        self.message_queue = queue.Queue()
        self.lock = threading.Lock()  # For thread-safe channel list updates
 
    def connect(self):
        try:
            # Create socket and wrap with SSL
            raw_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.irc = self.context.wrap_socket(raw_socket, server_hostname=self.server)
            print(f"Connecting to {self.server}:{self.port}...")
            self.irc.connect((self.server, self.port))
 
            # Send user and nick information
            self.send(f"USER {self.nickname} 0 * :{self.realname}")
            self.send(f"NICK {self.nickname}")
 
            return True
        except Exception as e:
            print(f"Connection error: {e}")
            return False
 
    def send(self, message):
        try:
            self.irc.send(f"{message}\r\n".encode('utf-8'))
        except Exception as e:
            print(f"Error sending message: {e}")
 
    def get_timestamp(self):
        # Return current time in 12-hour format (e.g., 3:45 PM) with blue ANSI color
        timestamp = datetime.now().strftime("%I:%M %p")
        return f"\033[34m[{timestamp}]\033[0m"
 
    def handle_input(self):
        while self.running:
            try:
                # Show prompt with active channel
                with self.lock:
                    prompt = f"[{self.active_channel}] > " if self.active_channel else "[No channel] > "
                sys.stdout.write(prompt)
                sys.stdout.flush()
                message = input().strip()
                if not self.running:
                    break
                if message:
                    self.message_queue.put(message)
            except KeyboardInterrupt:
                self.message_queue.put("QUIT :Goodbye")
                break
 
    def handle_server(self):
        while self.running:
            try:
                data = self.irc.recv(2048).decode('utf-8')
                if not data:
                    print(f"{self.get_timestamp()} Disconnected from server.")
                    self.running = False
                    break
 
                for line in data.strip().split('\r\n'):
                    if not line:
                        continue
                    # Add blue timestamp to all server lines
                    print(f"{self.get_timestamp()} {line}")
 
                    # Handle PING
                    if line.startswith("PING"):
                        self.send(f"PONG {line.split()[1]}")
 
                    # Join channels after MOTD
                    if "376" in line or "422" in line:
                        with self.lock:
                            for channel in self.channels:
                                self.send(f"JOIN {channel}")
                                print(f"{self.get_timestamp()} Joined {channel}")
                            self.active_channel = self.channels[0] if self.channels else None
 
                    # Parse messages for display
                    if "PRIVMSG" in line:
                        sender = line[1:line.index('!')]
                        target = line.split()[2]
                        msg = line[line.index(':', 1) + 1:]
                        # Timestamp already added above, just format the message
                        print(f"{self.get_timestamp()} <{sender}@{target}> {msg}")
 
                    # Handle channel join confirmation
                    if "JOIN" in line and self.nickname in line:
                        channel = line.split(':', 2)[-1]
                        with self.lock:
                            if channel not in self.channels:
                                self.channels.append(channel)
                                print(f"{self.get_timestamp()} Added {channel} to active channels.")
                                if not self.active_channel:
                                    self.active_channel = channel
 
                    # Handle parting a channel
                    if "PART" in line and self.nickname in line:
                        channel = line.split()[2]
                        with self.lock:
                            if channel in self.channels:
                                self.channels.remove(channel)
                                print(f"{self.get_timestamp()} Left {channel}")
                                if self.active_channel == channel:
                                    self.active_channel = self.channels[0] if self.channels else None
                                    print(f"{self.get_timestamp()} Active channel switched to: {self.active_channel or 'None'}")
 
            except Exception as e:
                print(f"{self.get_timestamp()} Server error: {e}")
                self.running = False
                break
 
    def process_commands(self):
        while self.running:
            try:
                message = self.message_queue.get(timeout=1)
                if message.lower() == "quit":
                    self.send("QUIT :Goodbye")
                    self.running = False
                elif message.startswith('/'):
                    self.handle_command(message)
                else:
                    # Send to active channel
                    with self.lock:
                        if self.active_channel:
                            self.send(f"PRIVMSG {self.active_channel} :{message}")
                        else:
                            print(f"{self.get_timestamp()} No active channel. Use /join <channel> or /switch <index>.")
            except queue.Empty:
                continue
            except Exception as e:
                print(f"{self.get_timestamp()} Command error: {e}")
 
    def handle_command(self, command):
        parts = command.split(maxsplit=2)
        cmd = parts[0].lower()
        if cmd == "/nick" and len(parts) > 1:
            self.nickname = parts[1]
            self.send(f"NICK {self.nickname}")
        elif cmd == "/join" and len(parts) > 1:
            channel = parts[1]
            self.send(f"JOIN {channel}")
            with self.lock:
                if channel not in self.channels:
                    self.channels.append(channel)
                    print(f"{self.get_timestamp()} Requested to join {channel}")
        elif cmd == "/msg" and len(parts) > 2:
            target = parts[1]
            msg = parts[2]
            self.send(f"PRIVMSG {target} :{msg}")
        elif cmd == "/list":
            with self.lock:
                if self.channels:
                    print(f"{self.get_timestamp()} Active channels:")
                    for i, channel in enumerate(self.channels):
                        mark = "*" if channel == self.active_channel else " "
                        print(f"{self.get_timestamp()}  {i}: {channel}{mark}")
                else:
                    print(f"{self.get_timestamp()} No channels joined.")
        elif cmd == "/part" and len(parts) > 1:
            channel = parts[1]
            self.send(f"PART {channel}")
        elif cmd == "/switch" and len(parts) > 1:
            try:
                index = int(parts[1])
                with self.lock:
                    if 0 <= index < len(self.channels):
                        self.active_channel = self.channels[index]
                        print(f"{self.get_timestamp()} Switched to active channel: {self.active_channel}")
                    else:
                        print(f"{self.get_timestamp()} Invalid index. Use /list to see channels.")
            except ValueError:
                print(f"{self.get_timestamp()} Invalid index. Use a number (e.g., /switch 0).")
        else:
            print(f"{self.get_timestamp()} Unknown command or invalid syntax. Try: /nick, /join, /msg, /list, /part, /switch")
 
    def run(self):
        if not self.connect():
            return
 
        # Start threads
        server_thread = threading.Thread(target=self.handle_server)
        input_thread = threading.Thread(target=self.handle_input)
        command_thread = threading.Thread(target=self.process_commands)
 
        server_thread.start()
        input_thread.start()
        command_thread.start()
 
        # Wait for threads to finish
        try:
            server_thread.join()
            input_thread.join()
            command_thread.join()
        except KeyboardInterrupt:
            self.running = False
 
        # Clean up
        self.irc.close()
        print(f"{self.get_timestamp()} Connection closed.")
 
def main():
    client = IRCClient()
    client.run()
 
if __name__ == "__main__":
    main()
 
</small></small>
</poem>
 
'''The client will:'''
 
#Connect to irc.rizon.net as LullSac.
#Attempt to join #/g/tv and #/sp/.
#Set #/g/tv as the active channel.
#Show a prompt like [#/g/tv] > .
#Display all messages with blue timestamps (e.g., [3:45 PM] <LullSac@#/g/tv> Hello).
 
'''Use the UI:'''
 
#Type messages (e.g., Hello) to send to the active channel (e.g., #/g/tv).
#'''/list''': See channels (e.g., 0: #/g/tv *, 1: #/sp/).
#'''/switch 1''': Switch to #/sp/ (prompt changes to [#/sp/] > ).
#'''/join #newchannel''': Join another channel.
#'''/part #/sp/''': Leave a channel.
#'''/msg #/g/tv''' Hi: Send to a specific channel.
#'''/nick NewName''': Change nickname.
#'''/msg SomeUser Hi''': Send a private message.
#'''quit''': Exit the client.


<h3>bombadillo</h3>
<h3>bombadillo</h3>

Revision as of 23:24, 30 April 2025

Anonymous 20:50, 4 August 2025 (EDT) Us.gif
Andy.jpg
Termux is a terminal emulator compatible with Xterm specification and Linux environment application for the Android OS. In other words this is an interface that lets you to run command line Linux programs. Additionally the app configures a lightweight environment that consists of standard utilities such as Bash, Coreutils, Nano, APT package manager and few other software packages.
Termux running irssi lets you chat with all your internet pals.

Some stuff I have found using termux terminal on my tablet. All of this stuff can be found on github and other websites and are probably a better source for the materials found here. I just copied and pasted stuff for my own personal use.

I am NOT a terminal (or linux) user. I dabble from time to time.

calcurse


Calcurse is a calendar and scheduling application for the command line. see more here.

To get it, you can install it in termux by typing:

pkg install calcurse

wordgrinder


WordGrinder is a Unicode-aware character cell word processor that runs in a terminal (or a Windows console). It is designed to get the hell out of your way and let you get some work done. You can see more here.

Install:

pkg install wordgrinder

wttr.in


Great way to get the local weather...if you happen to live in a town that has really recognizable name like Chicago or Berlin. Otherwise, you have to kinda play with it until it gets something close to what you want. Also, the ?u sets the temps to American units of F(reedom).

curl -s wttr.in/warsaw,IN?u

fastfetch


Screenshot 20250327 190230 Termux.jpg

Fastfetch displays what's going on.

Ways to install it here.

fastfetch --list-modules

Note that a lot of these do not work on Android.

1) Battery  : Print battery capacity, status, etc
2) Bios  : Print information of 1st-stage bootloader (name, version, release date, etc)
3) Bluetooth  : List (connected) bluetooth devices
4) BluetoothRadio: List bluetooth radios width supported version and vendor
5) Board  : Print motherboard name and other info
6) Bootmgr  : Print information of 2nd-stage bootloader (name, firmware, etc)
7) Break  : Print a empty line
8) Brightness  : Print current brightness level of your monitors
9) Btrfs  : Print Linux BTRFS volumes
10) Camera  : Print available cameras
11) Chassis  : Print chassis type (desktop, laptop, etc)
12) Command  : Run custom shell scripts
13) Colors  : Print some colored blocks
14) CPU  : Print CPU name, frequency, etc
15) CPUCache  : Print CPU cache sizes
16) CPUUsage  : Print CPU usage. Costs some time to collect data
17) Cursor  : Print cursor style name
18) Custom  : Print a custom string, with or without key
19) DateTime  : Print current date and time
20) DE  : Print desktop environment name
21) Display  : Print resolutions, refresh rates, etc
22) Disk  : Print partitions, space usage, file system, etc
23) DiskIO  : Print physical disk I/O throughput
24) DNS  : Print configured DNS servers
25) Editor  : Print information of the default editor ($VISUAL or $EDITOR)
26) Font  : Print system font names
27) Gamepad  : List (connected) gamepads
28) GPU  : Print GPU names, graphic memory size, type, etc
29) Host  : Print product name of your computer
30) Icons  : Print icon style name
31) InitSystem  : Print init system (pid 1) name and version
32) Kernel  : Print system kernel version
33) Keyboard  : List (connected) keyboards
34) LM  : Print login manager (desktop manager) name and version
35) Loadavg  : Print system load averages
36) Locale  : Print system locale name
37) LocalIp  : List local IP addresses (v4 or v6), MAC addresses, etc
38) Media  : Print playing song name
39) Memory  : Print system memory usage info
40) Monitor  : Alias of Display module
41) Mouse  : List connected mouses
42) NetIO  : Print network I/O throughput
43) OpenCL  : Print highest OpenCL version supported by the GPU
44) OpenGL  : Print highest OpenGL version supported by the GPU
45) OS  : Print operating system name and version
46) Packages  : List installed package managers and count of installed packages
47) PhysicalDisk  : Print physical disk information
48) PhysicalMemory: Print system physical memory devices
49) Player  : Print music player name
50) PowerAdapter  : Print power adapter name and charging watts
51) Processes  : Print number of running processes
52) PublicIp  : Print your public IP address, etc
53) Separator  : Print a separator line
54) Shell  : Print current shell name and version
55) Sound  : Print sound devices, volume, etc
56) Swap  : Print swap (paging file) space usage
57) Terminal  : Print current terminal name and version
58) TerminalFont  : Print font name and size used by current terminal
59) TerminalSize  : Print current terminal size
60) TerminalTheme : Print current terminal theme (foreground and background colors)
61) Title  : Print title, which contains your user name, hostname
62) Theme  : Print current theme of desktop environment
63) TPM  : Print info of Trusted Platform Module (TPM) Security Device
64) Uptime  : Print how long system has been running
65) Users  : Print users currently logged in
66) Version  : Print Fastfetch version
67) Vulkan  : Print highest Vulkan version supported by the GPU
68) Wallpaper  : Print image file path of current wallpaper
69) Weather  : Print weather information
70) WM  : Print window manager name and version
71) Wifi  : Print connected Wi-Fi info (SSID, connection and security protocol)
72) WMTheme  : Print current theme of window manager
73) Zpool  : Print ZFS storage pools

My current fastfetch:

fastfetch --logo none -s OS:Host:Memory:CPU:Battery:Disk:DateTime:Uptime

If you want to mess around with fastfetch logos (and there are a ton of them), check out:

fastfetch --list-logos

irssi


I don't normally use a CLI based irc client, but when I do, it is either irssi or weechat. Below you will find some irssi cheats.

irssi new user guide.

pkg install irssi

Irssi cheat sheet.jpg

When I use irssi, I don't like all the crap they put in the way. I just want text on a screen. Here are some things that will remove stuff that gets in the way:

/STATUSBAR MODIFY -disable info This gets rid of the info bar at the bottom that tells you stuff like how many users are in the channel.

/STATUSBAR MODIFY -disable window status bar This will remove the bar at the top that has the title in it.

fastfetch in irssi


I tried making a script that would output a fastfetch into a channel on irc:


use strict;
use vars qw($VERSION %IRSSI);
$VERSION = '1.5';
%IRSSI = (
    contact => 'N/A',
    name => 'Flexible Fastfetch Sysinfo',
    description => 'Displays system info on separate colored lines with fallbacks',
    license => 'Public Domain',
);
sub fetch_sysinfo {
    my ($server, $witem) = @_;
    return unless $witem; # Ensure we're in a channel/window
    # Run fastfetch and capture output
    my $sysinfo = `fastfetch --logo none -s OS:Memory:CPU:Battery:Disk:DateTime 2>/dev/null`;
    chomp($sysinfo);
    my %data;
    if ($sysinfo) {
        # Split by " - " and populate data hash
        my @sections = split / - /, $sysinfo;
        $data{'OS'} = $sections[0] if @sections > 0;
        $data{'Memory'} = $sections[1] if @sections > 1;
        $data{'CPU'} = $sections[2] if @sections > 2;
        $data{'Battery'} = $sections[3] if @sections > 3;
        $data{'Disk'} = $sections[4] if @sections > 4;
        $data{'Date & Time'} = $sections[5] if @sections > 5;
    }
    # Fallbacks for missing or incomplete data
    $data{'OS'} ||= `uname -o -r -m` || 'Unknown OS';
    $data{'Memory'} ||= `free -h | grep Mem | awk '{print \$3 "/" \$2}'` || 'Unknown Memory';
    $data{'CPU'} ||= `cat /proc/cpuinfo | grep "model name" | head -n 1 | cut -d: -f2-` || 'Unknown CPU';
    $data{'Battery'} ||= `termux-battery-status 2>/dev/null | grep percentage | cut -d: -f2 | tr -d '",'` || 'Unknown Battery';
    $data{'Disk (/)'}= `df -h / | tail -n 1 | awk '{print \$3 "/" \$2 " (" \$5 ")"}'` || 'Unknown Disk (/)';
    $data{'Disk (/storage/emulated)'} = `df -h /storage/emulated | tail -n 1 | awk '{print \$3 "/" \$2 " (" \$5 ")"}'` || 'Unknown Disk (/storage/emulated)';
    $data{'Date & Time'} ||= `date +"%Y-%m-%d %H:%M:%S"` || 'Unknown Date & Time';
    # Define colors and labels
    my @colors = (4, 7, 3, 12, 6, 9, 11); # Red, Orange, Green, Blue, Purple, Cyan, Light Cyan
    my @labels = ('OS:', 'Memory:', 'CPU:', 'Battery:', 'Disk (/):', 'Disk (/storage/emulated):', 'Date & Time:');
    # Send each line with colored values
    my $i = 0;
    for my $key ('OS', 'Memory', 'CPU', 'Battery', 'Disk (/)', 'Disk (/storage/emulated)', 'Date & Time') {
        chomp($data{$key}); # Remove newlines from fallback commands
        my $colored_value = "\x03" . $colors[$i % @colors] . $data{$key} . "\x0f";
        $witem->command("MSG " . $witem->{name} . " $labels[$i] " . $colored_value);
        $i++;
    }
}

  1. Register the /sysinfo command

Irssi::command_bind 'sysinfo' => sub {
    my ($data, $server, $witem) = @_;
    fetch_sysinfo($server, $witem);
};
print "Flexible Fastfetch Sysinfo script loaded. Use /sysinfo to display detailed system info!";

It kinda works. Some stuff runs together a bit.

curl wttr.in in irssi


Same thing as above, I tried getting a script to work that would display the current weather in my location in irssi.


use strict;
use vars qw($VERSION %IRSSI);
$VERSION = '1.1';
%IRSSI = (
    contact => 'N/A',
    name => 'Current Weather Fetcher',
    description => 'Fetches current weather for Warsaw, IN and sends it to the channel',
    license => 'Public Domain',
);
sub fetch_weather {
    my ($server, $witem) = @_;
    return unless $witem; # Ensure we're in a channel/window
    # Fetch only current weather using ?0 parameter
    my $weather = `curl -s wttr.in/warsaw,IN?u?0`;
    chomp($weather);
    if ($weather) {
        # Send the single-line current weather to the channel
        $witem->command("MSG " . $witem->{name} . " Current weather in Warsaw, IN: " . $weather);
    } else {
        $witem->command("MSG " . $witem->{name} . " Error: Could not fetch weather data.");
    }
}

  1. Register the /weather command

Irssi::command_bind 'weather' => sub {
    my ($data, $server, $witem) = @_;
    fetch_weather($server, $witem);
};
print "Current Weather Fetcher script loaded. Use /weather to display current Warsaw, IN weather!";

This one also half-ass works. I can't strip out the clouds/sun/rain that wttr.in displays.

lynx


Lynx is a text-based web browser designed for use in terminal environments, emphasizing accessibility, speed, and minimal resource usage. It renders web pages as plain text, stripping away images, JavaScript, and complex formatting, making it ideal for users who prioritize content over visual design or work in low-bandwidth or text-only systems.

I use it to access Gopher pages. To access them, you must type "lynx (address) into the termux command line.

Example:

lynx gopher://mozz.us:7003/

termux IRC client


See Termux IRC Client as all the code was moved there and will be updated more than this article.

bombadillo


Bombadillo is another Gopher browser for termux. It sucks. Don't use it.


Fauccitrans.png
Termux is part of a series that involves THE SCIENCE