Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > alt.os.linux.slackware > #35613
| From | jayjwa <jayjwa@atr2.ath.cx.invalid> |
|---|---|
| Newsgroups | alt.os.linux.slackware |
| Subject | countmail.py |
| Date | 2026-06-01 22:54 -0400 |
| Organization | atr2net 2026 |
| Message-ID | <87mrxdzm6p.fsf@atr2.ath.cx> (permalink) |
Following the discussion of it on LQ, I re-wrote BSD countmail because
that script is a bit bristly, requires eternal tools like "frm", and
doesn't handle Alpine/Pine's placeholder messages properly. This
version uses ANSI colors and works on SunOS too.
#!/usr/bin/python3
## countmail.py
## Rewrite of BSD countmail in basic Python to not use external tools
## and correctly handle Al/pine placeholder mails. Cross-platform for
## Linux, SunOS, probably others with Python3.
## $Id: countmail.py,v 1.1 2026/06/02 02:28:57 jayjwa Exp $
import os, sys, re
# ANSI color codes.
RED='\033[0;31m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
NC='\033[0m'
# Convert a number to its word equivalent. Handles up to 1 trillion.
def integerToWords( num ):
# dict to match an integer to its word value
d = { 0 : 'zero', 1 : 'one', 2 : 'two', 3 : 'three', 4 : 'four',
5 : 'five', 6 : 'six', 7 : 'seven', 8 : 'eight', 9 : 'nine',
10 : 'ten', 11 : 'eleven', 12 : 'twelve', 13 : 'thirteen',
14 : 'fourteen', 15 : 'fifteen', 16 : 'sixteen',
17 : 'seventeen', 18 : 'eighteen', 19 : 'nineteen',
20 : 'twenty', 30 : 'thirty', 40 : 'forty', 50 : 'fifty',
60 : 'sixty', 70 : 'seventy', 80 : 'eighty', 90 : 'ninety'
}
# thousands, millions, billions, trillions
k = 1000
m = k * 1000
b = m * 1000
t = b * 1000
# Shouldn't happen since there's no such thing as negative mail counts
if num < 0:
return d[ 0 ]
# Likewise
if num > 1000000000000:
# You don't really have that much mail...
sys.exit( f"{RED}You have too much mail!{NC}" )
# Recursively check the number, based on its size. Return the dict
# entry for that integer number.
if ( num < 20 ):
return d[ num ]
if ( num < 100 ):
if num % 10 == 0:
return d[ num ]
else:
return d[ num // 10 * 10 ] + '-' + d[ num % 10 ]
if ( num < k ):
if num % 100 == 0:
return d[ num // 100 ] + ' hundred'
else:
return d[ num // 100 ] + ' hundred and ' + integerToWords(num % 100)
if ( num < m ):
if num % k == 0:
return integerToWords( num // k ) + ' thousand'
else:
return integerToWords( num // k ) + ' thousand, ' + integerToWords( num % k )
if ( num < b ):
if ( num % m ) == 0:
return integerToWords( num // m ) + ' million'
else:
return integerToWords( num // m ) + ' million, ' + integerToWords( num % m )
if ( num < t ):
if ( num % b ) == 0:
return integerToWords( num // b ) + ' billion'
else:
return integerToWords( num // b ) + ' billion, ' + integerToWords( num % b )
if ( num % t == 0 ):
return integerToWords( num // t ) + ' trillion'
else:
return integerToWords( num // t ) + ' trillion, ' + integerToWords( num % t )
# First, locate the user's mail file. Respect env var, then search filesys.
mailfile = os.getenv( 'MAIL' )
if not mailfile:
# Try to construct a path to a mail file. LOGNAME is consistent
# across Linux and SunOS. Do not use "USER". Check popular places
# but don't go crazy digging for it.
if os.path.isfile( f"/var/mail/{os.getenv( 'LOGNAME' )}" ):
mailfile = f"/var/mail/{os.getenv( 'LOGNAME' )}"
elif os.path.isfile( f"/var/spool/mail/{os.getenv( 'LOGNAME' )}" ):
mailfile = f"/var/spool/mail/{os.getenv( 'LOGNAME' )}"
else:
# Still nothing? We can't work with no mail file.
sys.exit( f"{RED}Can't locate a mail file on this system!{NC}" )
# Regex to indicate that there is a mail message in the mail file. MUAs
# like Alpine and Pine have a placeholder message that must be excluded
# from the total count because it is not a real mail message.
mailPattern = re.compile( r'^From: *[^Mail System Internal Data]' )
count = 0
# Assume mailPattern is a mail occurance and count them
with open( mailfile, 'r' ) as mf:
for line in mf:
if re.match( mailPattern, line ):
count += 1
# "One" is singular, use "s" for the rest
if count == 1:
suffix = ""
else:
suffix = "s"
# This is the original display format for BSD countmail. More or less.
print( f"{GREEN}{ integerToWords( count ).upper() }!{NC}\n\n{GREEN}{ integerToWords( count ).capitalize() } mail message{suffix}!{NC}" )
print( f"{BLUE}HaHaHaHaHa!{NC}" )
## EOF
--
PGP Key ID: 781C A3E2 C6ED 70A6 B356 7AF5 B510 542E D460 5CAE
"The Internet should always be the Wild West!"
Back to alt.os.linux.slackware | Previous | Next — Next in thread | Find similar | Unroll thread
countmail.py jayjwa <jayjwa@atr2.ath.cx.invalid> - 2026-06-01 22:54 -0400
Re: countmail.py Eli the Bearded <*@eli.users.panix.com> - 2026-06-02 03:17 +0000
Re: countmail.py jayjwa <jayjwa@atr2.ath.cx.invalid> - 2026-06-02 11:28 -0400
Re: countmail.py (v2.1) jayjwa <jayjwa@atr2.ath.cx.invalid> - 2026-06-02 17:05 -0400
csiph-web