[Tutor] latest snapshot of TLpost.py

Kirk Bailey deliberatus@my995internet.com
Mon, 17 Dec 2001 14:39:42 -0500


Latest snapshot of TLpost.

Anyone want to look? Discussion, comments, suggestions all welcome.
Filthy jokes also, but 
they're off topic for this list (so email them to me seperately!)

rfc822 still leaves me blind. However, i wrote a fuction to load a file
and return one line from it.

Note how the footers are handled. 1 per list, 1 rotation per list, 1
footer for the entire service, 1
rotation for the entire service. If you do not want to use something,
leave it out and it is
bypassed. Samo for the REPLY-TO header field.

If we can simply grok the issness of rfc822, (and flesh out parsing the
from address), we got this
thing aced, and on to the web subscription manager.

-------------------------------------------------------------------------------------------------
#!/usr/local/bin/python
# Tinylist MLM Pitchtime module.
# COPYRIGHT 2002 Kirk D Bailey
# And made available under the GNU GPL.
#
#ADMIN AND LEGAL STUFF:
###############################################################################
# You should have received a copy of the GNU General Public
License           
# along with this program; if not, write to the Free
Software                 
#10
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
USA.
#
# Also, the GNU GPL may be viewed online at
# http://www.gnu.org/licenses/gpl.html
#########1#########2#########3#########4#########5#########6#########7#########8
#that line is 80 char across, try to stay within it if you can.
#
# "The tyrant's foe, the people's friend, a free press." -Dr Benjamin
Franklin.
#
###############################################################################
#21           Python can be studied and aquired at
http://www.python.org/ !!!
###############################################################################
#
# This module only handles receiving and sending out postings to a list.
# management of membership is handled by the favored command module
# - TLwebcommand, TLemailcommand, or both.
#
###############################################################################
#
# DEVLOPER'S NOTES:
# I have restored the old flavor of gangstrip, as the method we tried
had
# problems. This is larger and probably slower, but it works. -kdb
#
# I also have modified message processing so all the headers except to,
from
# are in msg itself, to comply with how sendmail() actually handles a
message.
# It just wants TO and FROM specified as variables, and the message as a
HUGE
# string with any other headers at the start of it. Recall that a body
of a 
# letter is preceeded with a blank line after the last header-
# that is, 
# (headlerdata)CRLFCRLFfirstlineofbodyCRLFsecondlineofbodyCRLF...
# -kdb
# 
# We also need to process the FROM address so we cook it down to a bare
assed
# email address with no decorations or extras.
# This is 'identity@domain.type' with NOTHING ELSE.
# we preserve the actual full data
# (such as '"Sean 'Shaleh' Perry" <shalehperry@attbi.com>'
# for politeness sake when dealing with the sending out
# of a posting. -kdb






# BEGIN PROCESSING PORTION
#######################################################
# we now import some functions from assorted libraries.
import sys, re, string, rfc822, smtplib, os.path

############################################################
# someday we will collect each needed function
# and create a module just of those and distribute it
# with tinylist. This will load faster, but will require
# the user to place it right and do other tech things most
# novices cringe from. And I don't blaim a novice from
# cringing, for the most part. -kdb
############################################################

# make sure you set this to YOUR domain!
localhost = 'howlermonkey.net'

# next line declares the path to stuff. DO NOT use a trailing '/'!

path = '/www/www.howlermonkey.net/cgi-bin'
print 'path=', path
# This ends the configuration portion. Hereafter only hackers need
venture.
###############################################################################

#

#

#

#

#

#

#

#

#

#

#

#

#

# WHAT?!? Still reading? ;-)

# we read a command line arguement to determine the list name
listname = sys.argv[1]

# Arguement #0 is the name of the script being run,
# #1 is the  first arguement after that name in the command line,
# so this tells us the  list name being addressed- listname!

# we append \r\n a lot, so we create a variable to contain that.
CRLF="\r\n"

# variable 'incoming' receives the entire incoming message
# which is piped to the script on <stdin> which this reads by the alias
# such as:
#         foolist:"|/pathtoprogram/programname foolist"
#
# Using rfc822.py, digest the message and make parts available to the
program.
Message = rfc822.Message(sys.stdin)



# now some code to debug with- remove it later.
type(Message)
print Message


# just strip off the leading and trailing whitespaces and
# place the resulting value in the variable.
# remember, 'FROM' is a reserved word in Python.
# I suspect 'TO' is also reserved.


# Extract the FROM data and copy it to a second storage variable to use
later-
# if there is a later.
RawSender = string.strip(Message['From'])
sender = RawSender
# preserve RawSender for later use,
# but process sender for the pure
# email address for membership testing.
print 'sender=', sender
print 'RawSender=', RawSender
# remove that print statement later.

# ADDRESS PROCESSING DUMMY CODE BLOCK
# We want to insert some code here replacing these lines
# to reduce sender to ONLY the word BEFORE '@',
# AFTER '@', and including '@' as 
# "me@here.foo"
# amd ignore any '<', '>'. or other words not in intimate contact with 
# that '@' symbol. 

subject= string.strip(Message['Subject'])
print 'Subject: ', subject

# The information is in the dictionary 'Message', each item keyed with
the
# header's name. The BODY of that dictionary is in the string 'msg'. So
are
# any attachments.
#
# Strip whitespace chars off every element in the list passed to this
function.
def gangstrip(thing):			# ok, everybody STRIP!
	index=0				# This strips out whitespace chars
	while index < len(thing):	# define exit
		thing[index]=string.strip(thing[index])
		index=index+1		# increase the counter

# and define fileoneline, which reads a file, selects one line at
random,
# and returns that as it's value.
def fileoneline(filename):
	f1=open(filename,'r')
	db=f1.readlines()
	f1.close()
	l=len(db)
	x=int(random.random()*l)
	return db[x]



# ok, let's read that membership file. it is named (listname)
# with no name extension.
f1 = open(path + "/lists/" + listname, 'r')						
members = f1.readlines()	# read all of it in.
f1.close()			# and close the file


# then we look to see if that FROM exists in the membership.
# clean it up;
gangstrip(members)		# strip all leading and trailing whitespace
				# from each element in the list 'members'.

# Ok, now er can start some real data processing!

msg="" 				# initiate a blank STRING variable for the
				# outgoing message.
				# then we look to see if the sender
				# is a member of the list:
if sender in members :		# IF sender is in members, they may post.
	msg = '[' + listname + ']' + subject + CRLF
	# Use OPIONAL reply-to field?
	if os.path.exists(path + "/lists/" +listname +".replyto"): 
		msg = msg + "Reply-to: " + listname + "@" + localhost + CRLF
	# Break email loops with other list servers from forming.
	msg = msg + "X-Loop: " + listname + "@" + localhost 
	
######################################################################
# need to add something to detect X=Loop header to STOP such posts!  #
# Simply ABORT the run if that header is present in the headers.     #
# if a message is QUOTED, it is in the BODY, ignore THAT. -kdb       #
######################################################################

# append incoming message body to outgoing message.
	rfc822.Rewindbody(Message) # set pointer to start of body.
				#  see http://www.python.org/doc/current/lib/message-objects.html
	msg = msg + Message	# for more details. rewindbody() rewinds to the
start of
the body.
	# that last line should add the body of the incoming message to the msg
variable.
	# the footer material is appended AFTER that, so if there is an
attachment, all
	# bloody hell will erupt- which is normal for list managers.
	
	# ok, here are 4 items that are optional.
	# a per list footer, a per list rotation, a global footer, a global
rotation.
	# these are turned on and off by the presence or absense of the
	# relevant file.
	# If you want more than one, duplicate that block, and change the
filename
	# reference. Remember, hackers only down here, yer on yer own.

	# append the list's static footer if there is one.
	if os.path.exists(path + "/lists/" + listname + ".footer"):
		f1=open(path + "/lists/" + listname + ".footer")
		ftr = fi.readlinies()
		f1.close()
		msg = msg + footer + CRLF 
 

	# append one line from the list's random rotation file if there is one.
	if os.path.exists(path + "/lists/"+listname+".random"):
		msg = msg + returnoneline(path + "/lists/"+listname+".random")

	# append the service's GLOBAL footer if there is one.
	if os.path.exists(path + "/lists/"+"global.footer"):
		f1=open(path + "/lists/" + "global.footer")
		f1.close()
		msg=msg + f1.readlines()


	# append one line from the GLOBAL ramdom rotation line if there is one.
	if os.path.exists(path + "/lists/"+"global.random"):
		msg = msg + returnoneline(path + "/lists/" + "global.footer")

	# other additions are certainly possible.
	# this ends processing for an acceptable posting.
	# Next block handles process for
	# REJECTED postings.
	#begin processing for a non member posting.
	
else:	# BUT IF THEY ARE NOT...
	listnamemembers = sender	# put poster address as the
					# ONLY recipient in list!
	msg = ""			# and clear the mesage.
	From_addr = "From: tinylist@" + localhost + CRLF
	msg = "Subject: Unauthorized posting to list: " + listname + CRLF
	msg = "Reply-to: postmaster@" + localhost + CRLF
	msg = "X-Loop: postmaster@" + localhost + CRLF
	msg = msg + CRLF + """To whom it may concern;

Sorry, but as you are not a current member of """ + listname + """, 
you may not post to it. Your recent posting has been rejected and
destroyed.

Feel free to contact the postmaster if there is any question.
Any reply to this letter should go directly to the postmaster.

You can also subscribe to this list if you like.

Goodbye.
	-Tiny the list robot.

"""

# End of alternate process. ABOVE IS 1 BLANK LINE, DO NOT DELETE IT!
# ok, if they are not a member, THEY GET 
# THE REPLY SHOWN ABOVE MAILED TO THEM! 
# (Maybe we could read a stock answer from a file?)


# now we send whatever message is to go out to 
# whatever is in the recipient list.
server = smtplib.SMTP('localhost')	# setup for a smtp run.
# helo(localhost)			# open a connection to the smtp server,
					# possibly not needed
					# so it is commented out.
					# If all else fails, use it.
server.connect()			# and log in to the thing 170
					# as the identity this script runs as.
for to_addr in listnamemembers :	# for each address in
'listnamemembers',
	server.sendmail(from_addr, to_addr, msg)
					# send envlope and msg!

					# don't delete the above line!
server.quit()				# then close the connection.

# make sure this script runs as a TRUSTED USER-
# and NOT as root!!! You set that up in the Sendmail
# Config file (sendmail.cf).
# Make sure that a NON-priviliged user OWNS
# this script, and that it runs as that identity!
#
# The TinyList community hangs out at www.tinylist.org
# and is a pretty informal and friendly bunch of digiteratti.
# Come visit!
#
# We have lists there, which only seems right somehow.
# they are:
# tinylist-users - discussion for all aspects of using
#                  tinylist; frequently quite technical.
#                  ask install and problem questions here.
#
# tinylist-chat - for all intrested in TL, lists, python,
#                 email: a broad charter! 
#
# tinylist-devlopers -	devlopers use this to suport the
#			devlopment of new versions, features, 
#			and bugchasing. *ROUTINELY* -VERY-
#			technical. NOI reccomended to the public.
#
# evil-humor - sick, raunchy, crusty, cynical, depraved, 
#               deprived humor? OVER HERE!
#
# Fnord.
-------------------------------------------------------------------------------------------------





-- 
Respectfully,
             -Kirk D Bailey (C)2001
              Addme! icq #27840081
end


Within the sweep of his sword, Each man is an Ubar.

http://www.howlermonkey.net/
http://www.sacredelectron.org/