pyss Python Sms Script
Verfasst: Samstag 10. September 2005, 16:10
Hallo Leute
mein Kumpel hat herausgefunden wie man mit Hilfe von smssend http://zekiller.skytech.org/smssend_menu_en.html über unseren Mobile-Provider gratis SMS verschicken kann und dazu ein kleines bash-Script geschrieben. Da der Funktionsumfang etwas ungenügend war, habe ich ein Python-Frontend dazu geschrieben.
pyss unterstützt das erstellen eines Adressbuches, das Personen und Gruppen enthalten kann und hat eine simple Log-Funktionalität. Ausserdem splitet es eine Nachricht automatisch auf die richtige Grösse, ohne Wörter zu zerhacken!
Seht es euch mal an:
Zugegeben, das Ganze hat noch ein paar Makel, Design-Fehler etc. Aber es ist soweit ganz brauchbar und neuere Versionen sollten diese auch ausbessern...
Gruss
Clython
mein Kumpel hat herausgefunden wie man mit Hilfe von smssend http://zekiller.skytech.org/smssend_menu_en.html über unseren Mobile-Provider gratis SMS verschicken kann und dazu ein kleines bash-Script geschrieben. Da der Funktionsumfang etwas ungenügend war, habe ich ein Python-Frontend dazu geschrieben.
pyss unterstützt das erstellen eines Adressbuches, das Personen und Gruppen enthalten kann und hat eine simple Log-Funktionalität. Ausserdem splitet es eine Nachricht automatisch auf die richtige Grösse, ohne Wörter zu zerhacken!
Seht es euch mal an:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: UTF8 -*-
# pyss version 0.2
# Author: Maël Mettler
# Home: www.mediamonger.ch
# e-mail: pyss@mediamonger.ch
# License: GNU v2
import sys
import os
import getopt
import pickle
class manageaccount:
"This class is used to manage the account information."
def __init__(self, account):
"The account information is contained in a tuple with 4 fields. Fields 0-3 are dictionaries (persons, groups and settings), field 3 is a list with the log data."
self.book = account
def showentry(self, section):
"Shows all entries of a section"
l = []
for item in self.book[section]:
l.append(item)
l.sort()
i = 0
for item in l:
length = len(item)
space = 15 - length
print i, item, space*" ", self.book[section][item]
i = i + 1
def addentry(self, key, value, section):
"Adds entry [key] with value [value] to [section]"
newentry = { key : value }
self.book[section].update(newentry)
def delentry(self, key, section):
"Deletes entry with key [key] in [section]"
del self.book[section][key]
def changeentry(self, key, newvalue, section):
"Changes entry with [key] to [newvalue] in [section]"
self.book[section][key]
newentry = { key : newvalue }
self.book[section].update(newentry)
class processsms:
"This class provides the functionalities to transform user input into data that sendsms can handle"
def __init__(self, data, message, recipients):
"Processsms takes 3 arguments: the data-dictionary, the message as a string and a list of recipients"
self.m = message
self.r = recipients
self.b = data
def getnumbers(self):
"This function resolves persons and groups to phonenumbers"
numbers = []
for item in self.r:
if self.b[0].has_key(item):
r1 = self.b[0][item], 1
numbers.append(r1)
elif self.b[1].has_key(item):
for i in self.b[1][item]:
r2 = self.b[0][i], 1
numbers.append(r2)
else:
if ismn(item):
r3 = ismn(item), 0
numbers.append(r3)
else:
numbers.append(item, 2)
numberofrecipients = len(numbers)
indexend = numberofrecipients - 1
x = self.demodulo(numberofrecipients, 9)
result = []
i = 1
while i <= x:
start = 9*(i-1)
end = (i*9)
if end > indexend:
end = indexend
else:
pass
result.append(numbers[9*(i-1) : (i*9)])
i = i + 1
return result
def tokenizemessage(self):
"This function splits the message to pieces smaller than 160 digits. If there is more than one piece then tokenizemessage adds pagecounts (ex. 1/5) to the beginning of each piece"
message = self.m + " " + self.b[2]["sig"]
messagelen = len(message)
numberofmessages = self.demodulo(messagelen, 144)
tokenlist = message.split()
countertoken = 0
endresultlist = []
midresultlist = []
tokenlistlength = len(tokenlist)
trigger = 1
triggerdel = 1
if numberofmessages == 1:
while trigger:
counterlength = 0
while counterlength < 144:
if countertoken < tokenlistlength:
midresultlist.append(tokenlist[countertoken])
if countertoken:
counterlength = counterlength + len(tokenlist[countertoken]) + 1
else:
counterlength = counterlength + len(tokenlist[countertoken])
countertoken = countertoken + 1
else:
trigger = 0
triggerdel = 0
counterlength = 160
countertoken = countertoken - 1
if triggerdel:
del midresultlist[-1]
else:
pass
result = " ".join(midresultlist)
endresultlist.append(result)
midresultlist = []
else:
messagexof = 1
while trigger:
counterlength = 0
while counterlength < 144:
if countertoken < tokenlistlength:
midresultlist.append(tokenlist[countertoken])
if not countertoken:
cnt = str(messagexof)+"/"+str(numberofmessages)+":"
counterlength = counterlength + len(tokenlist[countertoken]) + len(cnt) + 1
midresultlist.insert(0, cnt)
messagexof = messagexof + 1
elif not counterlength:
cnt = str(messagexof)+"/"+str(numberofmessages)+":"
counterlength = counterlength + len(tokenlist[countertoken]) + len(cnt) + 1
midresultlist.insert(0, str(messagexof)+"/"+str(numberofmessages)+": ")
messagexof = messagexof + 1
else:
counterlength = counterlength + len(tokenlist[countertoken]) + 1
countertoken = countertoken + 1
else:
trigger = 0
triggerdel = 0
counterlength = 160
countertoken = countertoken - 1
if triggerdel:
del midresultlist[-1]
else:
pass
result = " ".join(midresultlist)
endresultlist.append(result)
midresultlist = []
return endresultlist
def sendsms(self, messages, numbers):
"This function executes smssend by walking trough all pieces of a message and blocks of recipients"
messages.reverse()
for item in messages:
for block in numbers:
recipients = []
for recipient in block:
recipients.append(recipient[0])
length = len(item)
providerfile = self.b[2]["provider"]
nums = ";".join(recipients)
nums = nums.replace("\n", "")
numsm = nums.replace(";", "\n")
cmd = "smssend " + providerfile + ' "' + item + '" "' + nums + '"'
print "Sending:", item, "to\n", numsm
#print cmd
os.system(cmd)
def mgenerator(self):
"You can use mgenerator to test your application. It generates random messages"
import random
c = [ "1 ", "aa ", "aa ", "bbb ", "bbb ", "cccc ", "cccc ", "cccc ", "cccc ", "ddddd ", "ddddd ", "ddddd ", "ddddd ", "ddddd ", "eeeeee ", "fsdklfd ", "fdskgjsl ", "dfdgfifid "]
x = random.choice(c)
x = len(x)
y = random.choice(c)
y = len(y)
z = x * x * y
message = ""
for i in range(z):
word = random.choice(c)
message = message + word
return message
def ismn(self, numberoriginal):
"ismn makes sure that a phonenumber has the correct format"
number = numberoriginal.replace(" ", "")
number = number.replace(" ", "")
number = number.replace("/", "")
number = number.replace("'", "")
number = number.replace("+41", "0")
number = number.replace("0041", "0")
number = number.replace("(0)", "")
try:
int(number)
# 078 872 45 48 / +41 78 872 45 48
if len(number) == 10:
return number
except:
return numberoriginal, False
def demodulo(self, number, x):
"Demodulo returns the number of pieces that are needed to fit a list or a string of a ceratin length to appropriate pieces"
rest = number%x
multiplicator = (number - rest) / x
if rest:
return multiplicator + 1
else:
return multiplicator
class pyss:
"pyss provides the ui to the processsms class"
def __init__(self, data):
"init takes 1 argument: the data-tuple"
self.data = data
def usage(self):
"Print usage information"
print """
pyss [options]|recipients
[OPTIONS]
-h|--help shows this screen
-s|--setup setup pyss
-c|--change change pyss setup
-g|--group manage groups
-p|--person manage person
-C|--clean delete log
-l|--log show log entries
-i|--import import pb file
[Example]
pyss --help Shows this screen
pyss Send short message
pyss -s pyss setup
"""
def safe(self):
"Safe changes that were made in data"
datafilepath = self.data[2]["confighome"] + "/" + "pyssdata.pik"
datafile = open(datafilepath, "w")
pickle.dump(self.data, datafile)
datafile.close()
def send(self):
"ui to processsms.sendsms"
print "Recipients:"
recipients = raw_input()
recipient_list = recipients.split()
print "Message:"
message = raw_input()
sms = processsms(self.data, message, recipient_list)
finalr = sms.getnumbers()
finalm = sms.tokenizemessage()
sms.sendsms(finalm, finalr)
self.data[3].append((recipient_list, message))
self.safe()
def setup(self):
"Creates the setup data needed for pyss"
print "Doing setup"
person = {}
group = {}
setupdata = {}
home = raw_input("Please input path to your home (example: /home/linus")
smssendpath = home + "/.smssend"
if not os.path.exists(smssendpath):
os.mkdir(smssendpath, 0644)
out = 1
while out:
m0 = "Input your sendsms setup directory. (default = " + smssendpath + ")"
d = raw_input("""Input your sendsms setup directory. (default = ~/.smssend)""")
if d:
if os.path.exists(d):
out = 0
else:
print "Path does not exist. Shall I create:", d
print "Default = yes"
answer = raw_input()
if not answer or answer == "y" or answer == "yes":
os.mkdir(d, mode="0644")
out = 0
else:
pass
else:
d = smssendpath
out = 0
setupdata.update({ "confighome" : d })
out = 1
while out:
pf = raw_input("Input your provider file. (default = provider.sms)")
m1 = "Input path to your provider file. (default = " + smssendpath + ")"
ptpf = raw_input(m1)
if not pf and not ptpf:
path = d + "/provider.sms"
if os.path.exists(path):
out = 0
print "Provider file set to:", path
else:
print "Error! There is no providerfile! You have to get one for pyss and sendsms to work!"
elif pf and not ptpf:
path = d + "/" + pf
if os.path.exists(path):
out = 0
print "Provider file set to:", path
else:
print "Error! There is no providerfile! You have to get one for pyss and sendsms to work!"
elif not pf and ptpf:
path = ptpf + "/provider.sms"
if os.path.exists(path):
out = 0
print "Provider file set to:", path
else:
print "Error! There is no providerfile! You have to get one for pyss and sendsms to work!"
else:
path = ptpf + "/" + pf
if os.path.exists(path):
out = 0
print "Provider file set to:", path
else:
print "Error! There is no providerfile! You have to get one for pyss and sendsms to work!"
setupdata.update({ "provider" : path })
out = 1
while out:
pb = raw_input("If you have a phonebook-file (*.pb) please input path:")
if pb and os.path.exists(pb):
setupdata.update({ "pb" : pb })
out = 0
elif pb and not os.path.exists(pb):
print "This file does not exist. Please retry or go on."
else:
out = 0
sig = raw_input("Please input a signature (default = no signature:")
if not sig:
setupdata.update({ "sig" : "" })
else:
print "Set", sig, "as your signature"
setupdata.update({ "sig" : sig })
if setupdata.has_key("pb"):
result = importpb(setupdata["pb"])
person.update(result)
del setupdata["pb"]
else:
pass
completedata = (person, group, setupdata, [])
control = smsutils.manageaccount(completedata)
print "This are your settings:"
control.showentry(2)
q = raw_input("Is this correct? (default = yes)")
if not q or q == "yes" or q == "y":
pass
else:
changes(completedata)
safe(completedata)
def importpb(self, path):
"Import pb files from original sms-bash-script by Reto Glauser"
pb = open(path, "r")
line = pb.readline()
book = {}
while line:
line = line.replace("\n", "")
couple = line.split(":")
print "Set number", couple[1], "to person", couple[0]
result = raw_input("Default = yes")
if not result or result == "y" or result == "yes":
book.update({ couple[0]:couple[1]})
else:
pass
line = pb.readline()
return book
def importpb2(self, path):
"Same as importpb, but used directly from the shell"
print "Trying to import files with entries like this: person:phonenumber"
try:
pb = open(path, "r")
except:
print "File not found. Aborting!"
sys.exit()
line = pb.readline()
while line:
line = line.replace("\n", "")
couple = line.split(":")
try:
test = couple[1]
print "Set number", couple[1], "to person", couple[0]
result = raw_input("Default = yes: ")
if not result or result == "y" or result == "yes":
self.data.update({ couple[0]:couple[1]})
else:
pass
except:
print "This file is not in the correct format. Aborting!"
sys.exit()
line = pb.readline()
pb.close()
def changes(self):
"Change setup"
print "These are your settings.:"
control = smsutils.manageaccount(self.data)
control.showentry(2)
c = raw_input("Press [Enter] to exit\nInput the setting you want to change:\n")
if not c:
pass
else:
if self.data[2].has_key(c):
print "Enter new value for", c
new = raw_input()
self.data[2].changeentry(c, new)
else:
print "This setting does not exist!"
changes()
self.safe()
def managegroup(self):
"Manage your groups"
print "These are your groups:"
control = manageaccount(self.data)
if self.data[1]:
control.showentry(1)
else:
print "No groups available"
c = raw_input("Press [Enter] to exit:\nInput the group you want to change:\nInput a new group name to create a new entry:\n\n")
if not c:
sys.exit()
else:
if self.data[1].has_key(c):
print "Enter new value for", c
new = raw_input()
control.changeentry(c, new, 1)
else:
print "Creating new group", c
members = raw_input("Please input members of the group separated by a blank space:")
memberlist = members.split()
control.addentry(c, memberlist, 1)
self.safe()
self.managegroup()
def manageperson(self):
"Manage your persons"
print "These are the persons in your phonebook:"
control = manageaccount(self.data)
if self.data[0]:
control.showentry(0)
else:
print "No persons available"
c = raw_input("Press [Enter] to exit:\nInput the person you want to change:\nInput a new person to create a new entry:\n\n")
if not c:
sys.exit()
else:
if self.data[0].has_key(c):
print "Enter new value for", c
new = raw_input()
control.changeentry(c, new, 0)
else:
print "Creating new person", c
number = raw_input("Please input number of the person:")
control.addentry(c, number, 0)
self.safe()
self.manageperson()
def clean(self):
"clean log"
self.data = (self.data[0], self.data[1], self.data[2], [])
self.safe()
def logwrite(self):
"Show loginfo"
if not self.data[3]:
print "No log entries"
else:
for item in self.data[3]:
print "Wrote:"
print item[1]
print "to", " ".join(item[0])
def main():
try:
opts, args = getopt.getopt(sys.argv[1:], "hscgpCli:", ["help", "setup", "change", "group", "person", "clean", "log", "import="])
except getopt.GetoptError:
usage()
sys.exit(2)
try:
datafile = open( "/home/william/.smssend/pyssdata.pik", "r" )
data = pickle.load(datafile)
datafile.close()
except:
print "No config-file found! Performing setup"
ui = pyss({})
ui.setup()
sys.exit()
if not opts:
sms = pyss(data)
sms.send()
else:
ui = pyss(data)
for o, a in opts:
if o in ("-h", "--help"):
ui.usage()
sys.exit()
elif o in ("-s", "--setup"):
ui.setup()
sys.exit()
elif o in ("-c", "--change"):
ui.change()
sys.exit()
elif o in ("-g", "--group"):
ui.managegroup()
sys.exit()
elif o in ("-p", "--person"):
ui.manageperson()
sys.exit()
elif o in ("-C", "--clean"):
ui.clean()
sys.exit()
elif o in ("-l", "--log"):
ui.logwrite()
sys.exit()
elif o in ("-i", "--import"):
print a
ui.importpb2(a)
sys.exit()
else:
pass
main()
Gruss
Clython