--- a/iro/.eric4project/iro.e4p Sat Mar 24 00:02:42 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE UserProject SYSTEM "UserProject-4.0.dtd">
-<!-- eric4 user project file for project iro -->
-<!-- Saved: 2009-10-10, 13:26:41 -->
-<!-- Copyright (C) 2009 Sandro Knauß, bugs@sandroknauss.de -->
-<UserProject version="4.0">
-</UserProject>
--- a/iro/.eric4project/iro.e4q Sat Mar 24 00:02:42 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE UserProject SYSTEM "UserProject-4.0.dtd">
-<!-- eric4 user project file for project iro -->
-<!-- Saved: 2009-11-24, 02:01:06 -->
-<!-- Copyright (C) 2009 Sandro Knauß, bugs@sandroknauss.de -->
-<UserProject version="4.0">
-</UserProject>
\ No newline at end of file
--- a/iro/.eric4project/iro.e4t Sat Mar 24 00:02:42 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE Tasks SYSTEM "Tasks-4.2.dtd">
-<!-- eric4 tasks file for project iro -->
-<!-- Saved: 2009-11-24, 02:01:07 -->
-<Tasks version="4.2">
-</Tasks>
\ No newline at end of file
--- a/iro/MyIro_daemon.inst Sat Mar 24 00:02:42 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-#! /bin/sh
-NAME="Iro"
-USER=sandy
-HOMEDIR=/home/${USER}
-DEAMON=${HOMEDIR}/bin/MyIro
-DEAMON_OPTS=""
-PID=${HOMEDIR}/var/run/$NAME.pid
-
-test -x $DEAMON || exit 0
-
-. /lib/lsb/init-functions
-
-case "$1" in
- start)
- log_daemon_msg "Starting $NAME" $NAME
- if start-stop-daemon --start --quiet --background --oknodo --pidfile $PID --make-pidfile --user ${USER} --group ${USER} --chdir ${HOMEDIR} --startas $DEAMON -- $DEAMON_OPTS; then
- log_end_msg 0
- else
- log_end_msg 1
- fi
- ;;
- stop)
- log_daemon_msg "Stopping $NAME" $NAME
- if start-stop-daemon --stop --quiet --oknodo --pidfile $PID; then
- log_end_msg 0
- else
- log_end_msg 1
- fi
- ;;
-
- restart)
- $0 stop
- sleep 1
- $0 start
- ;;
-
- status)
- status_of_proc -p $PID $DEAMON $NAME && exit 0 || exit $?
- ;;
-
- *)
- log_action_msg "Usage: $0 {start|stop|restart|status}"
- exit 1
-esac
-
-exit 1
--- a/iro/acounting.py Sat Mar 24 00:02:42 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-# -*- coding: utf-8 -*-
-
-from database import Database
-import logging
-logger=logging.getLogger("iro.acounting");
-
-class Acounting(Database):
- def __init__(self,id, connection):
- Database.__init__(self,connection)
- self.id=id
-
- def setId(self,id, user):
- self.id=id
- if user:
- self.connect()
- self.cursor.execute ("INSERT INTO %s (id,user) VALUES ('%s','%s')" % (self.connection['overview'], self.id, user))
- self.disconnect()
-
-
- def getStatus(self):
- self.connect()
- self.cursor.execute ("SELECT status,tel FROM %s WHERE id='%s'" % (self.connection['table'], self.id))
- ret= self.cursor.fetchall()
- self.disconnect()
- return ret
-
- def addGood(self, good,disconnect=True):
- if type(good) == list:
- for i in good:
- self.addGood(i)
- if disconnect:
- self.disconnect()
- else:
- self.connect()
- self.cursor.execute("INSERT INTO %s (id,tel,status) VALUES('%s','%s','sended')" % (self.connection['table'], self.id, good))
- if disconnect:
- self.disconnect()
-
-
- def addFailed(self, failed,disconnect=True):
- if type(failed) == list:
- for i in failed:
- self.addFailed(i,False)
- if disconnect:
- self.disconnect()
- else:
- self.connect()
- self.cursor.execute ("INSERT INTO %s (id,tel,status) VALUES('%s','%s','failed')"%(self.connection['table'], self.id, failed))
- if disconnect:
- self.disconnect()
--- a/iro/anbieter/FAX_de.py Sat Mar 24 00:02:42 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-# -*- coding: utf-8 -*-
-#Copyright (C) 2009 Sandro Knauß <bugs@sandroknauss.de>
-
-#This program is free software; you can redistribute it and/or modify it under the terms
-#of the GNU General Public License as published by the Free Software Foundation;
-#either version 3 of the License, or any later version.
-#This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-#without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-#See the GNU General Public License for more details.
-
-#You should have received a copy of the GNU General Public License
-#along with this program; if not, see <http://www.gnu.org/licenses/>.
-
-from smtp import SMTP
-from geonet import geonet
-from telnumber import telnumber
-
-class FAX_de(geonet):
- section="FAX_de"
- default_conf="iro.conf"
- max_recipients=50
-
- def __init__(self):
- self.smtp=SMTP(self.default_conf,self.section)
-
- def createMailaddress(produkt,number):
- try:
- tel=telnumber(number)
- return "%s00%s%s@fax.de" %(produkt,tel.land,tel.number)
- except:
- return number
--- a/iro/anbieter/__init__.py Sat Mar 24 00:02:42 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-# -*- coding: utf-8 -*-
-#Copyright (C) 2009 Sandro Knauß <bugs@sandroknauss.de>
-
-#This program is free software; you can redistribute it and/or modify it under the terms
-#of the GNU General Public License as published by the Free Software Foundation;
-#either version 3 of the License, or any later version.
-#This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-#without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-#See the GNU General Public License for more details.
-
-#You should have received a copy of the GNU General Public License
-#along with this program; if not, see <http://www.gnu.org/licenses/>.
-
-from sipgate import sipgate
-from geonet import geonet
-from FAX_de import FAX_de
-from smtp import SMTP
-from smstrade import smstrade
-import content
--- a/iro/anbieter/anbieter.py Sat Mar 24 00:02:42 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-# -*- coding: utf-8 -*-
-#Copyright (C) 2009 Sandro Knauß <bugs@sandroknauss.de>
-
-#This program is free software; you can redistribute it and/or modify it under the terms
-#of the GNU General Public License as published by the Free Software Foundation;
-#either version 3 of the License, or any later version.
-#This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-#without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-#See the GNU General Public License for more details.
-
-#You should have received a copy of the GNU General Public License
-#along with this program; if not, see <http://www.gnu.org/licenses/>.
-
-class anbieter:
- default_conf = '' # override this
- section = 'anbieter' # override this
-
- def sendSMS(self,sms,recipients):
- pass
- def sendFAX(self,fax,recipients):
- pass
- def sendMail(self,mail,recipients):
- pass
-
- def setJob(self, job):
- self.job=job
--- a/iro/anbieter/geonet.py Sat Mar 24 00:02:42 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-# -*- coding: utf-8 -*-
-#Copyright (C) 2009 Sandro Knauß <bugs@sandroknauss.de>
-
-#This program is free software; you can redistribute it and/or modify it under the terms
-#of the GNU General Public License as published by the Free Software Foundation;
-#either version 3 of the License, or any later version.
-#This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-#without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-#See the GNU General Public License for more details.
-
-#You should have received a copy of the GNU General Public License
-#along with this program; if not, see <http://www.gnu.org/licenses/>.
-
-from smtp import SMTP
-from anbieter import anbieter
-from telnumber import telnumber
-
-from email import Encoders
-from email.MIMEMultipart import MIMEMultipart
-from email.MIMEBase import MIMEBase
-from email.MIMEText import MIMEText
-
-class Mail(MIMEMultipart):
- def __init__(self,send_from,header,cont,attachments):
- MIMEMultipart.__init__(self)
- self['From'] = send_from
- self['Subject']=header
- self.attach(MIMEText(cont))
- for attachment in attachments:
- part = MIMEBase('application', mimetypes.guess_type(attachment)[0])
- part.set_payload( open(attachment,"rb").read() )
- Encoders.encode_base64(part)
- art.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(f))
- self.attach(part)
-
-class geonet(anbieter):
- section="geonet"
- default_conf="iro.conf"
- max_recipients=50
-
- def __init__(self):
- self.smtp=SMTP(self.default_conf,self.section)
-
- def createMailaddress(produkt,number):
- try:
- tel=telnum(number)
- return "%s%s@%s.geonet.de" %(tel.land,tel.number,produkt)
- except:
- return number
-
- def sendSMS(self,sms,recipients):
- recps=[]
- for recpipient in recipients:
- recps.append(self.createMailadress(recpipient))
- self.sendMail(Mail(self.smtp.send_from,sms.content,"",[]),recps)
-
- def sendFAX(self,fax,recipients):
- recps=[]
- for recpipient in recipients:
- recps.append(self.createMailadress(recpipient))
- self.sendMail(Mail(self.smtp.send_from,"","",fax.attachments),recps)
--- a/iro/anbieter/gsm0338.py Sat Mar 24 00:02:42 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,192 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-import codecs
-import _multibytecodec as mbc
-
-ENCODING_NAME = "gsm0338"
-
-decoding_map= {
-unichr(0x00):unichr(0x0040), # COMMERCIAL AT
-unichr(0x01):unichr(0x00A3), # POUND SIGN
-unichr(0x02):unichr(0x0024), # DOLLAR SIGN
-unichr(0x03):unichr(0x00A5), # YEN SIGN
-unichr(0x04):unichr(0x00E8), # LATIN SMALL LETTER E WITH GRAVE
-unichr(0x05):unichr(0x00E9), # LATIN SMALL LETTER E WITH ACUTE
-unichr(0x06):unichr(0x00F9), # LATIN SMALL LETTER U WITH GRAVE
-unichr(0x07):unichr(0x00EC), # LATIN SMALL LETTER I WITH GRAVE
-unichr(0x08):unichr(0x00F2), # LATIN SMALL LETTER O WITH GRAVE
-unichr(0x09):unichr(0x00E7), # LATIN SMALL LETTER C WITH CEDILLA
-unichr(0x0A):unichr(0x000A), # LINE FEED
-unichr(0x0B):unichr(0x00D8), # LATIN CAPITAL LETTER O WITH STROKE
-unichr(0x0C):unichr(0x00F8), # LATIN SMALL LETTER O WITH STROKE
-unichr(0x0D):unichr(0x000D), # CARRIAGE RETURN
-unichr(0x0E):unichr(0x00C5), # LATIN CAPITAL LETTER A WITH RING ABOVE
-unichr(0x0F):unichr(0x00E5), # LATIN SMALL LETTER A WITH RING ABOVE
-unichr(0x10):unichr(0x0394), # GREEK CAPITAL LETTER DELTA
-unichr(0x11):unichr(0x005F), # LOW LINE
-unichr(0x12):unichr(0x03A6), # GREEK CAPITAL LETTER PHI
-unichr(0x13):unichr(0x0393), # GREEK CAPITAL LETTER GAMMA
-unichr(0x14):unichr(0x039B), # GREEK CAPITAL LETTER LAMDA
-unichr(0x15):unichr(0x03A9), # GREEK CAPITAL LETTER OMEGA
-unichr(0x16):unichr(0x03A0), # GREEK CAPITAL LETTER PI
-unichr(0x17):unichr(0x03A8), # GREEK CAPITAL LETTER PSI
-unichr(0x18):unichr(0x03A3), # GREEK CAPITAL LETTER SIGMA
-unichr(0x19):unichr(0x0398), # GREEK CAPITAL LETTER THETA
-unichr(0x1A):unichr(0x039E), # GREEK CAPITAL LETTER XI
-unichr(0x1B):unichr(0x00A0), # ESCAPE TO EXTENSION TABLE (or displayed as NBSP, see note above)
-unichr(0x1B0A):unichr(0x000C), # FORM FEED
-unichr(0x1B14):unichr(0x005E), # CIRCUMFLEX ACCENT
-unichr(0x1B28):unichr(0x007B), # LEFT CURLY BRACKET
-unichr(0x1B29):unichr(0x007D), # RIGHT CURLY BRACKET
-unichr(0x1B2F):unichr(0x005C), # REVERSE SOLIDUS
-unichr(0x1B3C):unichr(0x005B), # LEFT SQUARE BRACKET
-unichr(0x1B3D):unichr(0x007E), # TILDE
-unichr(0x1B3E):unichr(0x005D), # RIGHT SQUARE BRACKET
-unichr(0x1B40):unichr(0x007C), # VERTICAL LINE
-unichr(0x1B65):unichr(0x20AC), # EURO SIGN
-unichr(0x1C):unichr(0x00C6), # LATIN CAPITAL LETTER AE
-unichr(0x1D):unichr(0x00E6), # LATIN SMALL LETTER AE
-unichr(0x1E):unichr(0x00DF), # LATIN SMALL LETTER SHARP S (German)
-unichr(0x1F):unichr(0x00C9), # LATIN CAPITAL LETTER E WITH ACUTE
-unichr(0x20):unichr(0x0020), # SPACE
-unichr(0x21):unichr(0x0021), # EXCLAMATION MARK
-unichr(0x22):unichr(0x0022), # QUOTATION MARK
-unichr(0x23):unichr(0x0023), # NUMBER SIGN
-unichr(0x24):unichr(0x00A4), # CURRENCY SIGN
-unichr(0x25):unichr(0x0025), # PERCENT SIGN
-unichr(0x26):unichr(0x0026), # AMPERSAND
-unichr(0x27):unichr(0x0027), # APOSTROPHE
-unichr(0x28):unichr(0x0028), # LEFT PARENTHESIS
-unichr(0x29):unichr(0x0029), # RIGHT PARENTHESIS
-unichr(0x2A):unichr(0x002A), # ASTERISK
-unichr(0x2B):unichr(0x002B), # PLUS SIGN
-unichr(0x2C):unichr(0x002C), # COMMA
-unichr(0x2D):unichr(0x002D), # HYPHEN-MINUS
-unichr(0x2E):unichr(0x002E), # FULL STOP
-unichr(0x2F):unichr(0x002F), # SOLIDUS
-unichr(0x30):unichr(0x0030), # DIGIT ZERO
-unichr(0x31):unichr(0x0031), # DIGIT ONE
-unichr(0x32):unichr(0x0032), # DIGIT TWO
-unichr(0x33):unichr(0x0033), # DIGIT THREE
-unichr(0x34):unichr(0x0034), # DIGIT FOUR
-unichr(0x35):unichr(0x0035), # DIGIT FIVE
-unichr(0x36):unichr(0x0036), # DIGIT SIX
-unichr(0x37):unichr(0x0037), # DIGIT SEVEN
-unichr(0x38):unichr(0x0038), # DIGIT EIGHT
-unichr(0x39):unichr(0x0039), # DIGIT NINE
-unichr(0x3A):unichr(0x003A), # COLON
-unichr(0x3B):unichr(0x003B), # SEMICOLON
-unichr(0x3C):unichr(0x003C), # LESS-THAN SIGN
-unichr(0x3D):unichr(0x003D), # EQUALS SIGN
-unichr(0x3E):unichr(0x003E), # GREATER-THAN SIGN
-unichr(0x3F):unichr(0x003F), # QUESTION MARK
-unichr(0x40):unichr(0x00A1), # INVERTED EXCLAMATION MARK
-unichr(0x41):unichr(0x0041), # LATIN CAPITAL LETTER A
-unichr(0x42):unichr(0x0042), # LATIN CAPITAL LETTER B
-unichr(0x43):unichr(0x0043), # LATIN CAPITAL LETTER C
-unichr(0x44):unichr(0x0044), # LATIN CAPITAL LETTER D
-unichr(0x45):unichr(0x0045), # LATIN CAPITAL LETTER E
-unichr(0x46):unichr(0x0046), # LATIN CAPITAL LETTER F
-unichr(0x47):unichr(0x0047), # LATIN CAPITAL LETTER G
-unichr(0x48):unichr(0x0048), # LATIN CAPITAL LETTER H
-unichr(0x49):unichr(0x0049), # LATIN CAPITAL LETTER I
-unichr(0x4A):unichr(0x004A), # LATIN CAPITAL LETTER J
-unichr(0x4B):unichr(0x004B), # LATIN CAPITAL LETTER K
-unichr(0x4C):unichr(0x004C), # LATIN CAPITAL LETTER L
-unichr(0x4D):unichr(0x004D), # LATIN CAPITAL LETTER M
-unichr(0x4E):unichr(0x004E), # LATIN CAPITAL LETTER N
-unichr(0x4F):unichr(0x004F), # LATIN CAPITAL LETTER O
-unichr(0x50):unichr(0x0050), # LATIN CAPITAL LETTER P
-unichr(0x51):unichr(0x0051), # LATIN CAPITAL LETTER Q
-unichr(0x52):unichr(0x0052), # LATIN CAPITAL LETTER R
-unichr(0x53):unichr(0x0053), # LATIN CAPITAL LETTER S
-unichr(0x54):unichr(0x0054), # LATIN CAPITAL LETTER T
-unichr(0x55):unichr(0x0055), # LATIN CAPITAL LETTER U
-unichr(0x56):unichr(0x0056), # LATIN CAPITAL LETTER V
-unichr(0x57):unichr(0x0057), # LATIN CAPITAL LETTER W
-unichr(0x58):unichr(0x0058), # LATIN CAPITAL LETTER X
-unichr(0x59):unichr(0x0059), # LATIN CAPITAL LETTER Y
-unichr(0x5A):unichr(0x005A), # LATIN CAPITAL LETTER Z
-unichr(0x5B):unichr(0x00C4), # LATIN CAPITAL LETTER A WITH DIAERESIS
-unichr(0x5C):unichr(0x00D6), # LATIN CAPITAL LETTER O WITH DIAERESIS
-unichr(0x5D):unichr(0x00D1), # LATIN CAPITAL LETTER N WITH TILDE
-unichr(0x5E):unichr(0x00DC), # LATIN CAPITAL LETTER U WITH DIAERESIS
-unichr(0x5F):unichr(0x00A7), # SECTION SIGN
-unichr(0x60):unichr(0x00BF), # INVERTED QUESTION MARK
-unichr(0x61):unichr(0x0061), # LATIN SMALL LETTER A
-unichr(0x62):unichr(0x0062), # LATIN SMALL LETTER B
-unichr(0x63):unichr(0x0063), # LATIN SMALL LETTER C
-unichr(0x64):unichr(0x0064), # LATIN SMALL LETTER D
-unichr(0x65):unichr(0x0065), # LATIN SMALL LETTER E
-unichr(0x66):unichr(0x0066), # LATIN SMALL LETTER F
-unichr(0x67):unichr(0x0067), # LATIN SMALL LETTER G
-unichr(0x68):unichr(0x0068), # LATIN SMALL LETTER H
-unichr(0x69):unichr(0x0069), # LATIN SMALL LETTER I
-unichr(0x6A):unichr(0x006A), # LATIN SMALL LETTER J
-unichr(0x6B):unichr(0x006B), # LATIN SMALL LETTER K
-unichr(0x6C):unichr(0x006C), # LATIN SMALL LETTER L
-unichr(0x6D):unichr(0x006D), # LATIN SMALL LETTER M
-unichr(0x6E):unichr(0x006E), # LATIN SMALL LETTER N
-unichr(0x6F):unichr(0x006F), # LATIN SMALL LETTER O
-unichr(0x70):unichr(0x0070), # LATIN SMALL LETTER P
-unichr(0x71):unichr(0x0071), # LATIN SMALL LETTER Q
-unichr(0x72):unichr(0x0072), # LATIN SMALL LETTER R
-unichr(0x73):unichr(0x0073), # LATIN SMALL LETTER S
-unichr(0x74):unichr(0x0074), # LATIN SMALL LETTER T
-unichr(0x75):unichr(0x0075), # LATIN SMALL LETTER U
-unichr(0x76):unichr(0x0076), # LATIN SMALL LETTER V
-unichr(0x77):unichr(0x0077), # LATIN SMALL LETTER W
-unichr(0x78):unichr(0x0078), # LATIN SMALL LETTER X
-unichr(0x79):unichr(0x0079), # LATIN SMALL LETTER Y
-unichr(0x7A):unichr(0x007A), # LATIN SMALL LETTER Z
-unichr(0x7B):unichr(0x00E4), # LATIN SMALL LETTER A WITH DIAERESIS
-unichr(0x7C):unichr(0x00F6), # LATIN SMALL LETTER O WITH DIAERESIS
-unichr(0x7D):unichr(0x00F1), # LATIN SMALL LETTER N WITH TILDE
-unichr(0x7E):unichr(0x00FC), # LATIN SMALL LETTER U WITH DIAERESIS
-unichr(0x7F):unichr(0x00E0), # LATIN SMALL LETTER A WITH GRAVE
-}
-
-encoding_map=dict([(v,k) for (k,v) in decoding_map.items()])
-
-class Codec(codecs.Codec):
- def encode(self,input,errors='strict'):
- ret=""
- for i in input:
- ret+=encoding_map[i]
- return (ret,len(ret))
- def decode(self,input,errors='strict'):
- ret=""
- for i in input:
- ret+=decoding_map[i]
- return (ret,len(ret))
-
-
-
-class StreamWriter(Codec,mbc.MultibyteStreamWriter,codecs.StreamWriter):
- pass
-
-class StreamReader(Codec,mbc.MultibyteStreamReader,codecs.StreamReader):
- pass
-
-### encodings module API
-
-def getregentry():
- return (Codec().encode,Codec().decode,StreamReader,StreamWriter)
-
-
-def gsm_search(encoding):
- if not encoding == ENCODING_NAME:
- return
- return getregentry()
-
-# Register our codec when we load the module
-codecs.register(gsm_search)
-
-if __name__ == "__main__":
- text = "€öäüß"
- text2 = unicode(text,"utf-8").encode("gsm0338")
- assert(text2==u"\u1B65\x7C\x7B\x7E\x1E")
- text=""
- text2 = unicode(text,"utf-8").encode("gsm0338")
- assert(text==text2)
-
--- a/iro/anbieter/sipgate.py Sat Mar 24 00:02:42 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,157 +0,0 @@
-# -*- coding: utf-8 -*-
-#Copyright (C) 2009 Sandro Knauß <bugs@sandroknauss.de>
-
-#This program is free software; you can redistribute it and/or modify it under the terms
-#of the GNU General Public License as published by the Free Software Foundation;
-#either version 3 of the License, or any later version.
-#This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-#without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-#See the GNU General Public License for more details.
-
-#You should have received a copy of the GNU General Public License
-#along with this program; if not, see <http://www.gnu.org/licenses/>.
-
-
-from anbieter import anbieter
-from telnumber import telnumber, InvalidTel
-import ConfigParser
-import xmlrpclib
-import logging
-logger=logging.getLogger("sipgate")
-
-class NoValidStatusCode(Exception):
- def __init__(self, value):
- self.value = value
-
- def __str__(self):
- return repr(self.value)
-
-class sipgate(anbieter):
- """
- s. auch http://www.tuxad.com/sipgate.html
- und http://lists.sipgate.net/pipermail/sipgate-developers/2007-September/000016.html
- """
- section="sipgate"
- url="https://%s:%s@samurai.sipgate.net/RPC2"
- def __init__(self,user="",password=""):
- self.user=user
- self.password=password
-
- def read_basic_config(self,filenames):
- """Read basic options from the config file"""
- cp = ConfigParser.ConfigParser()
- cp.read(filenames)
- self.user=cp.get(self.section, 'user')
- self.password=cp.get(self.section, 'password')
-
- def sendSMS(self,sms,recipients):
- """send SMS with $sms to $recipients"""
- logger.debug('sipgate.sendSMS(%s,%s)'%(sms.getContent(), str(recipients)))
- args={
- "TOS" : "text",
- "Content" : sms.getContent()
- }
- self.__send(args,recipients)
-
- def sendFAX(self,fax,recipients):
- """send the PDF file $fax to $recipients"""
- logger.debug('sipgate.sendFAX(%s,%s)'%(fax, str(recipients)))
- args={
- "TOS" : "fax",
- "Content" : xmlrpclib.Binary(fax.getAttachment(0)),
- }
- self.__send(args,recipients)
-
- def __connect(self):
- """connect to sipgate XMLRPC Server"""
- logger.debug("sipgate.__connect()-"+self.url%(self.user,"XXXXXXXX"))
-
- self.serv=xmlrpclib.ServerProxy(self.url%(self.user,self.password))
- self.samurai=self.serv.samurai
-
- args_identify = {
- "ClientName" : "anbieter.py",
- "ClientVersion" : "V1.0",
- "ClientVendor" : "Sandro Knauss"
- }
- self.__send_method(self.samurai.ClientIdentify, args_identify)
- return self.serv
-
- def __send_method(self, func, args=None):
- """execute $func and test weather if the func ran successfully or not"""
- logger.debug("sipgate.__send_method(func,%s)"%( args))
-
- if args==None:
- xmlrpc_result = func()
- else:
- xmlrpc_result = func(args)
- if xmlrpc_result['StatusCode'] != 200:
- raise NoValidStatusCode("There was an error during identification to the server! %d %s"% (xmlrpc_result['StatusCode'], xmlrpc_result['StatusString']))
- logger.debug("sipgate.__send_method(..):ok");
- return xmlrpc_result
-
- def __send(self,args,recipients):
- """main sending method - sending the args to $recipients"""
- sended=[]
-
- serv=self.__connect()
- logger.debug('sipgate.__send(%s,%s)'%(args, recipients))
- for recipient in recipients:
- try:
- tel = telnumber(recipient)
-
- if tel in sended: #only send message once per recipient
- continue
- sended.append(tel)
-
- args["RemoteUri"]="sip:%s%s@sipgate.net"%(tel.land,tel.number)
- self.__send_method(serv.samurai.SessionInitiate, args)
- self.updateStatus(arranged=recipient)
-
- except (InvalidTel, NoValidStatusCode):
- self.updateStatus(failed=recipient)
-
- self.__disconnect()
-
- def updateStatus(self, arranged=None, failed=None):
- """is a function that is called, if a new SMS/FAX was send
- -arranged is non None, if SMS/FAX was sended successfully
- -failed is non None, if SMS/FAX sending failed
- the content will be the recipent"""
- pass
-
- def BalanceGet(self):
- """get the balance of sipgate"""
- self.__connect()
- ret = self.__send_method(self.samurai.BalanceGet )
- self.__disconnect()
- return ret['CurrentBalance']
-
- def getNewMessages(self):
- """get new messages from inbox"""
- self.__connect()
- tmp = self.__send_method(self.samurai.UmSummaryGet)
- self.__disconnect()
- tmp=tmp['UmSummary']
- ret={}
- for entry in tmp:
- ret[entry['TOS']]={'read':entry["Read"],'unread':entry["Unread"]}
- return ret
-
- def getRecommendedInterval(self,methods):
- """how often you can call one $methods"""
- self.__connect()
- args = {"MethodList" : methods }
- tmp = self.__send_method(self.samurai.RecommendedIntervalGet, args)
- self. __disconnect()
- ret={}
- for entry in tmp['IntervalList']:
- ret[entry['MethodName']]=entry['RecommendedInterval']
- return ret
-
- def __disconnect(self):
- """disconnect xmlrpc client"""
- logger.debug('sipgate.__disconnect()')
- self.samurai=None
- self.serv=None
- self.xmlrpc=None
--- a/iro/controller/task.py Sat Mar 24 00:02:42 2012 +0100
+++ b/iro/controller/task.py Sat Mar 24 00:07:40 2012 +0100
@@ -1,5 +1,6 @@
from functools import partial
+from twisted.python import log
from twisted.internet.defer import inlineCallbacks, returnValue, maybeDeferred, Deferred
from ..error import NoRouteForTask, RejectRecipient
@@ -44,15 +45,16 @@
offer = os.next()
d = maybeDeferred(offers[offer],self.recipient,self.job.message)
d.addCallback(self.d.callback)
- d.addErrback(addErr)
+ d.addErrback(addErr,offer)
d.addErrback(self.d.errback)
return d
except StopIteration:
self.d.errback(NoRouteForTask())
- def addErr(failure):
- failure.trap(RejectRecipient)
- return n()
+ def addErr(failure, offer):
+ if not isinstance(failure.value, RejectRecipient):
+ log.err(_why="Job(%s): Send to '%s' failed via '%s'"%(self.job.dbjob, self.recipient, offer),_stuff=failure)
+ n()
n()
--- a/iro/database.py Sat Mar 24 00:02:42 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import MySQLdb
-import sqlite3
-class Database(object):
- def __init__(self,connection):
- self.conn=None
- self.cursor=None
- self.connection=connection
- self.testConnection()
-
- def testConnection(self):
- self.connect()
- self.disconnect()
-
- def getConn(self):
- return self.conn
-
- def getCursor(self):
- return self.cursor
-
- def connect(self):
- if not self.getConn():
- if (self.connection['type']=='mysql'):
- self.conn=MySQLdb.connect(
- host = self.connection["host"],
- db = self.connection["db"],
- user = self.connection["user"],
- passwd = self.connection["passwd"],
- )
- if (self.connection['type']=='sqlite'):
- self.conn=sqlite3.connect(self.connection['path'])
-
- if not self.getCursor():
- self.cursor = self.conn.cursor()
-
- def disconnect(self):
- if self.getCursor():
- self.cursor.close()
- self.cursor=None
- if self.getConn():
- self.conn.close()
- self.conn=None
-
-
--- a/iro/install.py Sat Mar 24 00:02:42 2012 +0100
+++ b/iro/install.py Sat Mar 24 00:07:40 2012 +0100
@@ -1,3 +1,5 @@
+# -*- test-case-name: iro.tests.test_install -*-
+
from twisted.python import log
import logging
from sqlalchemy import create_engine
@@ -70,7 +72,8 @@
try:
ret["orphand"].remove(Offer.get(session, provider, r, t).name)
except:
- session.add(Offer(provider=provider,route=r,typ=t,name='%s_%s_%s'%(provider,t,r)))
+ if write:
+ session.add(Offer(provider=provider,route=r,typ=t,name='%s_%s_%s'%(provider,t,r)))
ret["added"].add("%s_%s_%s"%(provider,t,r))
return ret
--- a/iro/iro.api Sat Mar 24 00:02:42 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,163 +0,0 @@
-iro.anbieter.FAX_de.FAX_de.createMailaddress?4(number)
-iro.anbieter.FAX_de.FAX_de.default_conf?7
-iro.anbieter.FAX_de.FAX_de.max_recipients?7
-iro.anbieter.FAX_de.FAX_de.section?7
-iro.anbieter.FAX_de.FAX_de?1()
-iro.anbieter.anbieter.anbieter.default_conf?7
-iro.anbieter.anbieter.anbieter.section?7
-iro.anbieter.anbieter.anbieter.sendFAX?4(fax, recipients)
-iro.anbieter.anbieter.anbieter.sendMail?4(mail, recipients)
-iro.anbieter.anbieter.anbieter.sendSMS?4(sms, recipients)
-iro.anbieter.geonet.Mail?1(send_from, header, cont, attachments)
-iro.anbieter.geonet.geonet.createMailaddress?4(number)
-iro.anbieter.geonet.geonet.default_conf?7
-iro.anbieter.geonet.geonet.max_recipients?7
-iro.anbieter.geonet.geonet.section?7
-iro.anbieter.geonet.geonet.sendFAX?4(fax, recipients)
-iro.anbieter.geonet.geonet.sendSMS?4(sms, recipients)
-iro.anbieter.geonet.geonet?1()
-iro.anbieter.sipgate.sipgate.BalanceGet?4()
-iro.anbieter.sipgate.sipgate.__connect?6()
-iro.anbieter.sipgate.sipgate.__disconnect?6()
-iro.anbieter.sipgate.sipgate.__send?6(args, recipients)
-iro.anbieter.sipgate.sipgate.__send_method?6(func, args=None)
-iro.anbieter.sipgate.sipgate.getNewMessages?4()
-iro.anbieter.sipgate.sipgate.getRecommendedInterval?4(methods)
-iro.anbieter.sipgate.sipgate.read_basic_config?4(filename)
-iro.anbieter.sipgate.sipgate.section?7
-iro.anbieter.sipgate.sipgate.sendFAX?4(fax, recipients)
-iro.anbieter.sipgate.sipgate.sendSMS?4(sms, recipients)
-iro.anbieter.sipgate.sipgate.updateStatus?4(arranged=None, failed=None)
-iro.anbieter.sipgate.sipgate.url?7
-iro.anbieter.sipgate.sipgate?1(user="", password="")
-iro.anbieter.smstrade.InternetConnectionError.__str__?6()
-iro.anbieter.smstrade.InternetConnectionError?1(url)
-iro.anbieter.smstrade.__send?6(self, key, route, to, message, from_=None, timestamp=None)
-iro.anbieter.smstrade.sendSMS?4(self, sms, recipients)
-iro.anbieter.smstrade.smstrade.read_basic_config?4(filename)
-iro.anbieter.smstrade.smstrade.section?7
-iro.anbieter.smstrade.smstrade.url?7
-iro.anbieter.smstrade.smstrade?1()
-iro.anbieter.smstrade.updateStatus?4(self, arranged=None, failed=None)
-iro.anbieter.smtp.SMTP.prepareSMTP?4()
-iro.anbieter.smtp.SMTP.read_basic_config?4(config_filename=None)
-iro.anbieter.smtp.SMTP.sendMail?4(mail, recipients)
-iro.anbieter.smtp.SMTP.shutdownSMTP?4()
-iro.anbieter.smtp.SMTP.updateStatus?4(arranged=None, failed=None)
-iro.anbieter.smtp.SMTP?1(config_filename=None, section="smtp")
-iro.anbieter.smtp.anbieter.default_conf?7
-iro.anbieter.telnumber.NotATelNumber.__str__?6()
-iro.anbieter.telnumber.NotATelNumber?1(number)
-iro.anbieter.telnumber.anbieter.default_conf?7
-iro.anbieter.telnumber.telnumber.__eq__?6(y)
-iro.anbieter.telnumber.telnumber.__ne__?6(y)
-iro.anbieter.telnumber.telnumber.createNumber?4(number)
-iro.anbieter.telnumber.telnumber.re_land?7
-iro.anbieter.telnumber.telnumber.re_number?7
-iro.anbieter.telnumber.telnumber.re_telnum?7
-iro.anbieter.telnumber.telnumber.std_land?7
-iro.anbieter.telnumber.telnumber?1(number=None)
-iro.anbieter.test.TestTelnumber.equalNumber?4(tel1, tel2)
-iro.anbieter.test.TestTelnumber.testEqual?4()
-iro.anbieter.test.TestTelnumber.testNumber?4()
-iro.anbieter.test.TestTelnumber.testWrongNumber?4()
-iro.anbieter.test.anbieter.default_conf?7
-iro.content.FAX.sendto?4(anbieter, recipients)
-iro.content.FAX?1(header, cont, attachments)
-iro.content.Mail.as_string?4()
-iro.content.Mail.sendto?4(anbieter, recipients)
-iro.content.Mail?1(subject, body)
-iro.content.SMS.sendto?4(anbieter, recipients)
-iro.content.SMS?1(cont)
-iro.content.content.sendto?4(anbieter, recipients)
-iro.content.content?1(content)
-iro.iro.MyManager.certificate?7
-iro.iro.MyManager.userdb?7
-iro.iro.MySMTP.setJob?4(job)
-iro.iro.MySMTP.updateStatus?4(arranged=None, failed=None)
-iro.iro.MySMTP?1(config_filename=None, section="smtp")
-iro.iro.MySipgate.setJob?4(job)
-iro.iro.MySipgate.updateStatus?4(arranged=None, failed=None)
-iro.iro.MySipgate?1(user="", password="")
-iro.iro.MySmstrade.setJob?4(job)
-iro.iro.MySmstrade.updateStatus?4(arranged=None, failed=None)
-iro.iro.MySmstrade?1()
-iro.iro.MyUserDB.createUser?4(user)
-iro.iro.MyUserDB?1(userlist, jobqueue)
-iro.iro.start?4(userlist)
-iro.job.Job.addFailed?4(failed)
-iro.job.Job.addGood?4(good)
-iro.job.Job.getName?4()
-iro.job.Job.getProvider?4()
-iro.job.Job.getStatus?4(detailed)
-iro.job.Job.start?4()
-iro.job.Job.stop?4()
-iro.job.Job?1(provider, name)
-iro.job.MessageJob.getMessage?4()
-iro.job.MessageJob.getRecipients?4()
-iro.job.MessageJob.start?4()
-iro.job.MessageJob.stop?4()
-iro.job.MessageJob?1(provider, name, message, recipients)
-iro.joblist.Joblist.__getitem__?6(key)
-iro.joblist.Joblist.__registerJob__?6(job)
-iro.joblist.Joblist._createID?5()
-iro.joblist.Joblist.newFAX?4(subject, fax, recipients)
-iro.joblist.Joblist.newMail?4(subject, body, recipients)
-iro.joblist.Joblist.newSMS?4(message, recipients)
-iro.joblist.Joblist?1(manager, queue, providerlist)
-iro.providerlist.Providerlist.add?4(name, provider, typeslist)
-iro.providerlist.Providerlist.getDefault?4(stype)
-iro.providerlist.Providerlist.getProvider?4(stype, name="default")
-iro.providerlist.Providerlist.getProviderlist?4(stype)
-iro.providerlist.Providerlist.setDefault?4(stype, name)
-iro.providerlist.Providerlist?1()
-iro.test.MyManager.certificate?7
-iro.test.MyManager.userdb?7
-iro.test.StoppableXMLRPCServer.run?4()
-iro.test.StoppableXMLRPCServer.running?7
-iro.test.StoppableXMLRPCServer.stop?4()
-iro.test.StoppableXMLRPCServer?1(*args, **kwargs)
-iro.test.TestServer.setUp?4()
-iro.test.TestServer.tearDown?4()
-iro.test.TestServer.testGetDefault?4()
-iro.test.TestServer.testGetProvider?4()
-iro.test.TestServer.testLogin?4()
-iro.test.TestServer.testTwoUser?4()
-iro.test.TestServer.testsendSMS?4()
-iro.test.init_server?4()
-iro.user.Admin?1(jobqueue)
-iro.user.NotSupportedFeature.__str__?6()
-iro.user.NotSupportedFeature?1(name)
-iro.user.User.getDefaultProvider?4(name)
-iro.user.User.getProvider?4(name)
-iro.user.User.startFAX?4()
-iro.user.User.startMail?4(subject, body, recipients)
-iro.user.User.startSMS?4(message, recipients)
-iro.user.User.status?4(id=None, detailed=False)
-iro.user.User.stop?4(id)
-iro.user.User?1(jobqueue)
-iro.worker.Worker.run?4()
-iro.worker.Worker?1(queue)
-iro.xmlrpc.AuthentificateXMLRPCServer.AuthentificateXMLRPCRequestHandler.do_POST?4()
-iro.xmlrpc.AuthentificateXMLRPCServer.AuthentificateXMLRPCRequestHandler.report_401?4()
-iro.xmlrpc.AuthentificateXMLRPCServer.AuthentificateXMLRPCRequestHandler.report_error?4(code)
-iro.xmlrpc.AuthentificateXMLRPCServer.AuthentificateXMLRPCRequestHandler.testUser?4(username, password)
-iro.xmlrpc.AuthentificateXMLRPCServer.test?4()
-iro.xmlrpc.SecureAuthentificateXMLRPCServer.SecureAuthentificateXMLRPCRequestHandler.do_POST?4()
-iro.xmlrpc.SecureAuthentificateXMLRPCServer.test?4()
-iro.xmlrpc.SecureUserdbXMLRPCServer.SecureAuthentificateXMLRPCRequestHandler2.testUser?4(username, password)
-iro.xmlrpc.SecureUserdbXMLRPCServer.SecureUserDBXMLRPCServer.activateUser?4(username, password)
-iro.xmlrpc.SecureUserdbXMLRPCServer.SecureUserDBXMLRPCServer?1(addr, userdb, requestHandler=SecureAuthentificateXMLRPCRequestHandler2, certificate="server.cert", privatekey="server.pem", logRequests=1)
-iro.xmlrpc.SecureUserdbXMLRPCServer.UserDB.__getitem__?6(key)
-iro.xmlrpc.SecureUserdbXMLRPCServer.UserDB.createHash?4(user)
-iro.xmlrpc.SecureUserdbXMLRPCServer.UserDB.createUser?4(user)
-iro.xmlrpc.SecureUserdbXMLRPCServer.UserDB?1(userClass, userlist, jobqueue)
-iro.xmlrpc.SecureXMLRPCServer.SSLWrapper.__getattr__?6(name)
-iro.xmlrpc.SecureXMLRPCServer.SSLWrapper.__setattr__?6(name, value)
-iro.xmlrpc.SecureXMLRPCServer.SSLWrapper.accept?4()
-iro.xmlrpc.SecureXMLRPCServer.SSLWrapper.shutdown?4(how=1)
-iro.xmlrpc.SecureXMLRPCServer.SSLWrapper?1(conn)
-iro.xmlrpc.SecureXMLRPCServer.SecureTCPServer?1(server_address, RequestHandlerClass, certificate, privatekey)
-iro.xmlrpc.SecureXMLRPCServer.SecureXMLRPCRequestHandler.setup?4()
-iro.xmlrpc.SecureXMLRPCServer.SecureXMLRPCServer?1(addr, requestHandler=SecureXMLRPCRequestHandler, certificate="server.cert", privatekey="server.pem", logRequests=1)
-iro.xmlrpc.SecureXMLRPCServer.test?4()
\ No newline at end of file
--- a/iro/iro.e4p Sat Mar 24 00:02:42 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,225 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE Project SYSTEM "Project-4.6.dtd">
-<!-- eric4 project file for project iro -->
-<!-- Saved: 2009-11-23, 00:15:34 -->
-<!-- Copyright (C) 2009 Sandro Knauß, bugs@sandroknauss.de -->
-<Project version="4.6">
- <Language></Language>
- <ProgLanguage mixed="0">Python</ProgLanguage>
- <ProjectType>Console</ProjectType>
- <Description>Ein Daemon zum Senden von Massensms, -faxen und emails</Description>
- <Version>0.1</Version>
- <Author>Sandro Knauß</Author>
- <Email>bugs@sandroknauss.de</Email>
- <Sources>
- <Source>iro.py</Source>
- <Source>__init__.py</Source>
- <Source>xmlrpc/SecureXMLRPCServer.py</Source>
- <Source>xmlrpc/__init__.py</Source>
- <Source>xmlrpc/SecureAuthentificateXMLRPCServer.py</Source>
- <Source>xmlrpc/AuthentificateXMLRPCServer.py</Source>
- <Source>xmlrpc/SecureUserdbXMLRPCServer.py</Source>
- <Source>worker.py</Source>
- <Source>user.py</Source>
- <Source>test.py</Source>
- <Source>providerlist.py</Source>
- <Source>joblist.py</Source>
- <Source>job.py</Source>
- <Source>anbieter/smtp.py</Source>
- <Source>anbieter/geonet.py</Source>
- <Source>anbieter/content.py</Source>
- <Source>anbieter/__init__.py</Source>
- <Source>anbieter/telnumber.py</Source>
- <Source>anbieter/test.py</Source>
- <Source>anbieter/FAX_de.py</Source>
- <Source>anbieter/sipgate.py</Source>
- <Source>anbieter/gsm0338.py</Source>
- <Source>anbieter/anbieter.py</Source>
- <Source>anbieter/smstrade.py</Source>
- </Sources>
- <Forms>
- </Forms>
- <Translations>
- </Translations>
- <Resources>
- </Resources>
- <Interfaces>
- </Interfaces>
- <Others>
- <Other>iro.conf.inst</Other>
- <Other>iro.conf</Other>
- </Others>
- <MainScript>iro.py</MainScript>
- <Vcs>
- <VcsType>None</VcsType>
- <VcsOptions>
- <dict>
- <key>
- <string>add</string>
- </key>
- <value>
- <list>
- <string></string>
- </list>
- </value>
- <key>
- <string>checkout</string>
- </key>
- <value>
- <list>
- <string></string>
- </list>
- </value>
- <key>
- <string>commit</string>
- </key>
- <value>
- <list>
- <string></string>
- </list>
- </value>
- <key>
- <string>diff</string>
- </key>
- <value>
- <list>
- <string></string>
- </list>
- </value>
- <key>
- <string>export</string>
- </key>
- <value>
- <list>
- <string></string>
- </list>
- </value>
- <key>
- <string>global</string>
- </key>
- <value>
- <list>
- <string></string>
- </list>
- </value>
- <key>
- <string>history</string>
- </key>
- <value>
- <list>
- <string></string>
- </list>
- </value>
- <key>
- <string>log</string>
- </key>
- <value>
- <list>
- <string></string>
- </list>
- </value>
- <key>
- <string>remove</string>
- </key>
- <value>
- <list>
- <string></string>
- </list>
- </value>
- <key>
- <string>status</string>
- </key>
- <value>
- <list>
- <string></string>
- </list>
- </value>
- <key>
- <string>tag</string>
- </key>
- <value>
- <list>
- <string></string>
- </list>
- </value>
- <key>
- <string>update</string>
- </key>
- <value>
- <list>
- <string></string>
- </list>
- </value>
- </dict>
- </VcsOptions>
- <VcsOtherData>
- <dict>
- <key>
- <string>standardLayout</string>
- </key>
- <value>
- <bool>True</bool>
- </value>
- </dict>
- </VcsOtherData>
- </Vcs>
- <FiletypeAssociations>
- <FiletypeAssociation pattern="*.pyw" type="SOURCES" />
- <FiletypeAssociation pattern="*.idl" type="INTERFACES" />
- <FiletypeAssociation pattern="*.py" type="SOURCES" />
- <FiletypeAssociation pattern="*.ptl" type="SOURCES" />
- </FiletypeAssociations>
- <Documentation>
- <DocumentationParams>
- <dict>
- <key>
- <string>ERIC4API</string>
- </key>
- <value>
- <dict>
- <key>
- <string>basePackage</string>
- </key>
- <value>
- <unicode>iro</unicode>
- </value>
- <key>
- <string>ignoreFilePatterns</string>
- </key>
- <value>
- <list>
- <unicode></unicode>
- </list>
- </value>
- <key>
- <string>includePrivate</string>
- </key>
- <value>
- <bool>True</bool>
- </value>
- <key>
- <string>languages</string>
- </key>
- <value>
- <list>
- <unicode>Python</unicode>
- </list>
- </value>
- <key>
- <string>outputFile</string>
- </key>
- <value>
- <unicode>iro.api</unicode>
- </value>
- <key>
- <string>useRecursion</string>
- </key>
- <value>
- <bool>True</bool>
- </value>
- </dict>
- </value>
- </dict>
- </DocumentationParams>
- </Documentation>
-</Project>
\ No newline at end of file
--- a/iro/iro.py Sat Mar 24 00:02:42 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,177 +0,0 @@
-# -*- coding: utf-8 -*-
-#Copyright (C) 2009 Sandro Knauß <bugs@sandroknauss.de>
-
-#This program is free software; you can redistribute it and/or modify it under the terms
-#of the GNU General Public License as published by the Free Software Foundation;
-#either version 3 of the License, or any later version.
-#This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-#without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-#See the GNU General Public License for more details.
-
-#You should have received a copy of the GNU General Public License
-#along with this program; if not, see <http://www.gnu.org/licenses/>.
-
-import multiprocessing, logging
-#logging anfangen
-logger=logging.getLogger("iro")
-logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(name)s(%(processName)s)-%(levelname)s: %(message)s')
-
-
-# Server code
-from xmlrpc import SecureUserDBXMLRPCServer,UserDB
-
-from user import User, Admin
-import anbieter
-import ConfigParser
-
-from job import SMSJob, FAXJob, MailJob
-from joblist import Joblist
-from providerlist import Providerlist
-from acounting import Acounting
-
-class MyUserDB(UserDB):
- def __init__(self, userlist,jobqueue):
- UserDB.__init__(self, None,userlist,jobqueue)
-
- def createUser(self, user):
- self.userlist[self.createHash(user)]=user["class"](user["name"],self.jobqueue)
-
-
-
-
-class MySipgate(anbieter.sipgate):
-
- def __init__(self,user="",password="" ):
- anbieter.sipgate.__init__(self, user, password)
-
- def setJob(self, job):
- self.job=job
-
- def updateStatus(self, arranged=None, failed=None):
- if arranged:
- self.job.addGood(arranged)
-
- if failed:
- self.job.addFailed(failed)
-
-class MySMTP(anbieter.SMTP):
-
- def __init__(self,config_filename=None,section="smtp"):
- anbieter.SMTP.__init__(self,config_filename,section)
-
- def setJob(self, job):
- self.job=job
-
- def updateStatus(self, arranged=None, failed=None):
- if arranged:
- self.job.addGood(arranged)
-
- if failed:
- self.job.addFailed(failed)
-
-class MySmstrade(anbieter.smstrade):
-
- def __init__(self ):
- anbieter.smstrade.__init__(self )
-
- def setJob(self, job):
- self.job=job
-
- def updateStatus(self, arranged=None, failed=None):
- if arranged:
- self.job.addGood(arranged)
-
- if failed:
- self.job.addFailed(failed)
-
-
-
-def start(userlist):
- from multiprocessing import Queue
- from multiprocessing.managers import BaseManager
-
-
- class MyManager(BaseManager):
- pass
-
- MyManager.register('SMSJob', SMSJob)
- MyManager.register('FaxJob', FAXJob)
- MyManager.register('MailJob',MailJob)
- MyManager.register('Providerlist',Providerlist)
- MyManager.register('Acounting',Acounting)
- manager = MyManager()
- manager.start()
-
-
- conf=["iro.conf", "~/iro.conf","/etc/iro/iro.conf"]
-
- #anbieter erzeugen und konfigurieren
-
- sip=MySipgate()
- sip.read_basic_config(conf)
-
- localhost=MySMTP()
- localhost.read_basic_config(conf)
-
- smstrade=MySmstrade()
- smstrade.read_basic_config(conf)
-
- cp = ConfigParser.ConfigParser()
- cp.read(conf)
- dbconn={'type':cp.get('db', 'type'),
- 'host':cp.get('db', 'host'),
- 'db':cp.get('db', 'db'),
- 'user':cp.get('db', 'user'),
- 'passwd':cp.get('db', 'passwd'),
- 'table':cp.get('db', 'table'),
- }
-
-
- #Benutzerdatenbank erstellen
- queue = Queue()
- provider=manager.Providerlist()
- provider.add("sipgate", sip, ["sms", "fax", ])
- provider.add("smstrade", smstrade, ["sms", ])
- #provider.add("geonet", None, ["sms", "fax", ])
- #provider.add("fax.de", None, ["sms", "fax", ])
- provider.add("localhost", localhost, ["mail", ])
- provider.setDefault("sms","smstrade")
- provider.setDefault("fax","sipgate")
- provider.setDefault("mail","localhost")
- jobqueue=Joblist(manager, queue, provider,dbconn)
-
- userdb=MyUserDB(userlist,jobqueue)
-
- #working thread erstellen
- from worker import Worker
- worker=Worker(queue)
- worker.start()
-
- #Server starten
- cp = ConfigParser.ConfigParser()
- cp.read(conf)
- cert=cp.get('server', 'cert')
- key=cp.get('server', 'key')
- server = SecureUserDBXMLRPCServer(addr=("localhost", 8000),
- userdb=userdb,
- certificate=cert,privatekey=key)
- server.relam="xmlrpc"
-
- logger.info('Server gestartet...')
- try:
- server.serve_forever()
- except KeyboardInterrupt:
- pass
- except:
- logger.exception('Äh, ein Fehler ist aufgetreten')
- finally:
- logger.info('Server wird beendet...')
- queue.close()
- worker.terminate()
-
-if __name__ == '__main__':
- userlist=[{"name":"test","password":"test", "class":User},
- {"name":"test2","password":"test2", "class": Admin}]
- start(userlist)
-
-
--- a/iro/job.py Sat Mar 24 00:02:42 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,121 +0,0 @@
-# -*- coding: utf-8 -*-
-#Copyright (C) 2009 Sandro Knauß <bugs@sandroknauss.de>
-
-#This program is free software; you can redistribute it and/or modify it under the terms
-#of the GNU General Public License as published by the Free Software Foundation;
-#either version 3 of the License, or any later version.
-#This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-#without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-#See the GNU General Public License for more details.
-
-#You should have received a copy of the GNU General Public License
-#along with this program; if not, see <http://www.gnu.org/licenses/>.
-
-class Job(object):
- '''
- Basic class for all jobs
- '''
- def __init__(self,providerlist,provider, name):
- self.providerlist=providerlist
- self.provider=provider
- self.name=name
- self.status = "init"
- self.dStatus={"good":[], "failed":[]}
- self.id=None
- self.acounting=None
-
- def setAcounting(self,ac):
- self.acounting=ac
-
- def setId(self, id):
- self.id=id
- if self.acounting:
- self.acounting.setId(id)
-
- def start(self,indifier=None):
- self.indifier=indifier
- self.status = "started"
-
- def stop(self):
- self.status = "stopped"
-
- def setLog(self,log):
- self.log=log
-
- def getStatus(self,detailed=False):
- if detailed and self.status == "started" or self.status == "sended":
- return self.status, self.dStatus
- return self.status,{}
-
- def setStatus(self,status):
- self.status=status
-
- def getName(self):
- return self.name
-
- def getProvider(self):
- return None
-
- def addGood(self, good):
- if self.acounting:
- self.acounting.addGood(good)
- if type(good) == list:
- self.dStatus['good']=self.dStatus['good']+good
- else:
- self.dStatus['good'].append(good)
-
- def addFailed(self, failed):
- if self.acounting:
- self.acounting.addFailed(failed)
- if type(failed) == list:
- self.dStatus['failed']=self.dStatus['failed']+failed
- else:
- self.dStatus['failed'].append(failed)
-
-class MessageJob(Job):
- '''
- A specialized class for smsjobs
- '''
- def __init__(self,providerlist,provider, name, message,recipients):
- self.message=message
- self.recipients=recipients
- Job.__init__(self,providerlist,provider, name)
-
- def stop(self):
- pass
-
- def start(self, id=None):
- Job.start(self,id)
- self.getProvider().setJob(self)
- self.message.sendto(self.getProvider(), self.recipients)
- self.status="sended"
-
- def getMessage(self):
- return self.message
-
- def getRecipients(self):
- return self.recipients
-
-
-class SMSJob(MessageJob):
- def __init__(self,providerlist,provider, name, message,recipients):
- MessageJob.__init__(self,providerlist,provider, name, message,recipients)
-
- def getProvider(self):
- return self.providerlist.getProvider("sms", self.provider)
-
-class FAXJob(MessageJob):
- def __init__(self,providerlist,provider, name, message,recipients):
- MessageJob.__init__(self,providerlist,provider, name, message,recipients)
-
- def getProvider(self):
- return self.providerlist.getProvider("fax", self.provider)
-
-class MailJob(MessageJob):
- def __init__(self,providerlist,provider, name, message,recipients):
- MessageJob.__init__(self,providerlist,provider, name, message,recipients)
-
- def getProvider(self):
- return self.providerlist.getProvider("mail", self.provider)
-
-
--- a/iro/joblist.py Sat Mar 24 00:02:42 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-# -*- coding: utf-8 -*-
-#Copyright (C) 2009 Sandro Knauß <bugs@sandroknauss.de>
-
-#This program is free software; you can redistribute it and/or modify it under the terms
-#of the GNU General Public License as published by the Free Software Foundation;
-#either version 3 of the License, or any later version.
-#This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-#without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-#See the GNU General Public License for more details.
-
-#You should have received a copy of the GNU General Public License
-#along with this program; if not, see <http://www.gnu.org/licenses/>.
-
-from anbieter import content
-import hashlib, os, time
-import logging
-logger=logging.getLogger("iro.joblist");
-
-class Joblist:
- '''
- Providing an list of jobs; each new job gets a hash id
- '''
- def __init__(self,manager, queue,providerlist,dbconn=None):
- self.jobs={}
- self.manager=manager
- self.queue=queue
- self.providerlist=providerlist
- self.dbconn=dbconn
-
-
- def __getitem__(self,key):
- return self.jobs[key]
-
- def __registerJob__(self, job, user):
- id = self._createID()
- if self.dbconn:
- job.setAcounting(self.manager.Acounting(id,self.dbconn))
- job.setId(id, user)
- self.jobs[id]=job
- self.queue.put(job)
- return id
-
- def newSMS(self, message, recipients, provider="default", user=None):
- '''
- creates a new SMS
- '''
- job=self.manager.SMSJob(self.providerlist, provider,message, content.SMS(message),recipients)
- return self.__registerJob__(job,user)
-
- def newFAX(self,subject, fax,recipients,provider="default",user=None):
- '''
- creates a new Fax
- '''
- job=self.manager.FaxJob(self.providerlist, provider,subject, content.FAX(subject,'' ,fax),recipients)
- return self.__registerJob__(job,user)
-
- def newMail(self, subject, body, recipients, frm, provider="default",user=None):
- '''
- creates a new Mail
- '''
- job=self.manager.MailJob(self.providerlist, provider,subject, content.Mail(subject, body, frm),recipients)
- return self.__registerJob__(job,user)
-
- def _createID(self):
- '''
- creats a random hash id
- '''
- while True:
- m = hashlib.sha1()
- m.update(str(time.time()))
- m.update(os.urandom(10))
- if not self.jobs.has_key(m.hexdigest):
- if not self.dbconn:
- self.jobs[m.hexdigest()]=None
- break
- if not self.manager.Acounting(m.hexdigest(),self.dbconn).getStatus():
- self.jobs[m.hexdigest()]=None
- break
- return m.hexdigest()
--- a/iro/model/job.py Sat Mar 24 00:02:42 2012 +0100
+++ b/iro/model/job.py Sat Mar 24 00:07:40 2012 +0100
@@ -1,5 +1,4 @@
-from twisted.python import log
-from twisted.python import threadable
+from twisted.python import log, threadable
from datetime import datetime
from collections import MutableMapping
@@ -21,6 +20,7 @@
self.tasks={}
self.c = 0
self.status = "started"
+ log.msg("Job(%s) created."%(self.dbjob))
def addTask(self,task):
self.tasks[task.recipient] = task
@@ -37,6 +37,7 @@
return
job.status = status
self.status = status
+ log.msg("Job(%s) status changed to: %s."%(self.dbjob, status))
session.commit()
@dbdefer
@@ -44,10 +45,10 @@
c = self.incStatus()
job = schema.Job.get(session, self.dbjob)
- if job.status in ["started","init"]:
- self._status(session,"sending")
if c == len(self.recipients):
self._status(session,"sended")
+ elif job.status in ["started","init"]:
+ self._status(session,"sending")
if status.costs > 0:
o = schema.Offer.get(session, status.provider.name, status.route, self.message.typ)
--- a/iro/model/message.py Sat Mar 24 00:02:42 2012 +0100
+++ b/iro/model/message.py Sat Mar 24 00:07:40 2012 +0100
@@ -21,16 +21,12 @@
class SMS(Message):
def __init__(self, cont, from_ = None):
- Message.__init__(self, cont, typ="sms")
+ Message.__init__(self, cont.encode("utf-8"), typ="sms")
self.from_ = from_
- def sendto(self,anbieter,recipients):
- anbieter.sendSMS(self,recipients)
-
-
class Fax(Message):
def __init__(self,header,cont,attachments=[]):
- Message.__init__(self,cont, typ="fax")
+ Message.__init__(self,cont.encode("utf-8"),typ="fax")
self.header=header
self.attachments=attachments
--- a/iro/newinterface.py Sat Mar 24 00:02:42 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,269 +0,0 @@
-# -*- coding: utf-8 -*-
-#Copyright (C) 2009 Sandro Knauß <bugs@sandroknauss.de>
-
-#This program is free software; you can redistribute it and/or modify it under the terms
-#of the GNU General Public License as published by the Free Software Foundation;
-#either version 3 of the License, or any later version.
-#This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-#without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-#See the GNU General Public License for more details.
-
-#You should have received a copy of the GNU General Public License
-#along with this program; if not, see <http://www.gnu.org/licenses/>.
-from twisted.web import soap, xmlrpc, resource, server
-import logging
-logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(name)s(%(processName)s)-%(levelname)s: %(message)s')
-
-
-class User(object):
- def __init__(self,name,userhash):
- self.name=name
- self.userhash=userhash
-
- def __repr__(self):
- return"User<'%s','%s'>"%(self.name,self.userhash)
-
-users={"1":User("spam","1"),
- "2":User("foo","2")
-}
-
-def getuser(userhash):
- try:
- return users[userhash]
- except KeyError:
- raise UserNotFound()
-
-def with_user(f):
- def new_f(*args,**kargs):
- args=list(args)
- logging.debug("Entering %s"%f.__name__)
- try:
- kargs["user"]=getuser(kargs["apikey"])
- del kargs["apikey"]
- except KeyError:
- kargs["user"]=getuser(args[1])
- del args[1]
- ret=f(*args,**kargs)
- logging.debug("Exited %s"%f.__name__)
- return ret
- new_f.__name__ = f.__name__
- return new_f
-
-
-class InterfaceException(Exception):
- def __init__(self, code=999, msg="Unbekannter Fehler."):
- self.code=code
- self.msg=msg
-
- def dict(self):
- return {"code":self.code,
- "msg":self.msg,
- }
- def __str__(self):
- return "%i:%s"%(self.code,self.msg)
-
-class UserNotFound(InterfaceException):
- def __init__(self):
- InterfaceException.__init__(self, 901, "Der API-Key ist ungültig.")
-
-class ExternalException(InterfaceException):
- def __init__(self):
- InterfaceException.__init__(self, 950, "Fehler in externer API.")
-
-
-class Interface(object):
- '''class for a xmlrpc user
- '''
-
- @with_user
- def status(self, user, id=None, detailed=False):
- '''Gibt den aktuellen Status eines Auftrages oder Mehreren zurück.
-
- Keywords:
- apikey[string]: Der API Key
- id[hash]: Eine Auftragsnummer
- detailed[boolean]: Details ausgeben
-
- Return:
- jobs[list]: Eine Liste der Aufträge.
- job.name[string]: Angebener Name
- job.status[string]: Status des Auftrages
-
-
- '''
- #return user.status(id,detailed)
- return ""
-
- @with_user
- def stop(self, user, id):
- '''Stoppt den angegeben Auftrag.
-
- Keywords:
- apikey[string]: Der API Key
- id[hash]: Eine Auftragsnummer
-
- Return:
-
- '''
- return ""
-
- @with_user
- def sms(self, user, message, recipients, route="default"):
- '''Versendet eine SMS.
-
- Keywords:
- apikey[string]: Der API Key
- message[string]: Nachricht
- recipients[list]: eine Liste von Emfänger-Nummern (gemäß ITU-T E.123)
- route[string|list]: Route über den geschickt werden soll,
- oder eine Liste von Routen, um Fallbacks anzugeben
-
- Return:
- id[hash]: Die ID des Auftrages
-
- '''
- return ""
-
- @with_user
- def fax(self, user, subject, fax, recipients, route="default"):
- '''Versendet ein FAX.
-
- Keywords:
- apikey[string]: Der API Key
- subject[string]: Der Betreff
- fax[string]: Das PDF base64 kodiert
- recipients[list]: Eine Liste von Emfänger-Nummern (gemäß ITU-T E.123)
- route[string|list]: Route über den geschickt werden soll,
- oder eine Liste von Routen, um Fallbacks anzugeben
-
- Return:
- id[hash]: Die ID des Auftrages
-
- '''
- return ""
-
- @with_user
- def mail(self, user, subject, body, recipients, frm, route="default"):
- '''Versendet eine Email.
-
- Keywords:
- apikey[string]: Der API Key
- subject[string]: Der Betreff
- body[string]: Der Email Body
- recipients[list]: Eine Liste von Emailadressen
- frm[string]: Die Absender Emailadresse
- route[string|list]: Route über den geschickt werden soll,
- oder eine Liste von Routen, um Fallbacks anzugeben
-
- Return:
- id[hash]: Die ID des Auftrages
-
- '''
- return ""
-
- @with_user
- def routes(self, user, typ):
- '''Gibt eine Liste aller verfügbaren Provider zurück.
-
- Keywords:
- apikey[string]: Der API Key
- typ[string]: Der Typ zu dem die Providerloste ausgeben werden soll
- Einer der Liste ["sms","fax","mail"]
-
- Return:
- providerlist[list]: Eine Liste aller möglichen Provider
-
- '''
- return ""
-
- @with_user
- def defaultRoute(self, user, typ):
- '''Gibt den Standardprovider zurück.
-
- Keywords:
- apikey[string]: Der API Key
- typ[string]: Der Typ zu dem die Providerloste ausgeben werden soll
- Einer der Liste ["sms","fax","mail"]
-
- Return:
- provider[string]: Der Standardprovider für den angeben Typ
-
-
- '''
- return ""
-
- @with_user
- def statistic(self, user):
- '''Gibt eine Statik zurück über die versendendeten Nachrichten und des Preises.
-
- Keywords:
- apikey[string]: Der API Key
-
- Return:
- statistic[list]: Eine Liste nach Nachrichtentypen
- '''
- return ""
-
- def listMethods(self):
- """Since we override lookupProcedure, its suggested to override
- listProcedures too.
- """
- return self.listProcedures()
-
-
- def listProcedures(self):
- """Since we override lookupProcedure, its suggested to override
- listProcedures too.
- """
- return ['listMethods','status','stop','sms','fax','mail','routes','defaultRoute','statistic']
-
-
-class XMLRPCInterface(Interface,xmlrpc.XMLRPC):
- def __init__(self):
- xmlrpc.XMLRPC.__init__(self)
- Interface.__init__(self)
-
- def lookupProcedure(self, procedurePath):
- logging.debug("lookupProcedure('%s')"%procedurePath)
- if procedurePath not in self.listProcedures():
- raise xmlrpc.NoSuchFunction(self.NOT_FOUND,
- "procedure %s not found" % procedurePath)
- try:
- return getattr(self,procedurePath)
- except KeyError:
- raise xmlrpc.NoSuchFunction(self.NOT_FOUND,
- "procedure %s not found" % procedurePath)
-
-class SOAPInterface(Interface,soap.SOAPPublisher):
- def __init__(self):
- soap.SOAPPublisher.__init__(self)
- Interface.__init__(self)
-
- def lookupFunction(self, functionName):
- """Lookup published SOAP function.
-
- Override in subclasses. Default behaviour - publish methods
- starting with soap_, if they have true attribute useKeywords
- they are expected to accept keywords.
-
- @return: tuple (callable, useKeywords), or (None, None) if not found.
- """
- if functionName in self.listProcedures():
- function = getattr(self, functionName, None)
- if function:
- return function, getattr(function, "useKeywords", False)
- return None
- else:
- return None
-
-
-def main():
- from twisted.internet import reactor
- root = resource.Resource()
- root.putChild('RPC2', XMLRPCInterface())
- root.putChild('SOAP', SOAPInterface())
- reactor.listenTCP(7080, server.Site(root))
- reactor.run()
-
-if __name__ == '__main__':
- main()
--- a/iro/offer/smstrade.py Sat Mar 24 00:02:42 2012 +0100
+++ b/iro/offer/smstrade.py Sat Mar 24 00:07:40 2012 +0100
@@ -112,7 +112,7 @@
parameters= {"key": self.key,
"route": route,
"to": to,
- "message": sms.content.encode("utf-8"),
+ "message": sms.content,
"charset":"utf-8",
"debug": self.testmode,
"message_id":True,
@@ -127,7 +127,7 @@
length=len(sms.content)
for s in doubleChar:
- length += sms.content.encode("utf-8").count(s)
+ length += sms.content.count(s)
parameters["concat_sms"] = True if length > 160 else False
ps={}
--- a/iro/providerlist.py Sat Mar 24 00:02:42 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-# -*- coding: utf-8 -*-
-#Copyright (C) 2009 Sandro Knauß <bugs@sandroknauss.de>
-
-#This program is free software; you can redistribute it and/or modify it under the terms
-#of the GNU General Public License as published by the Free Software Foundation;
-#either version 3 of the License, or any later version.
-#This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-#without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-#See the GNU General Public License for more details.
-
-#You should have received a copy of the GNU General Public License
-#along with this program; if not, see <http://www.gnu.org/licenses/>.
-
-class Providerlist:
- def __init__(self):
- self.provider={}
- self.types={}
- self.defaults={}
-
- def add(self, name, provider, typeslist):
- self.provider[name]={"name":name, "class":provider, "types":typeslist}
- for stype in typeslist:
- try:
- self.types[stype].append(self.provider[name])
- except KeyError:
- self.types[stype]=[self.provider[name]]
-
-
- def setDefault(self, stype, name):
- self.defaults[stype]=self.provider[name]
-
- def getDefault(self, stype):
- return self.defaults[stype]
-
- def getProviderlist(self, stype):
- llist=[ provider["name"] for provider in self.types[stype] ]
- llist.sort()
- return llist
-
- def status(self):
- ret="provider:%s"%self.provider
- ret +="\ntypes:%s"%self.types
- return ret+"\ndefaults:%s"%self.defaults
-
- def getProvider(self, stype, name="default"):
- if name=="default":
- return self.getDefault(stype)["class"]
-
- if not stype in self.provider[name] ["types"]:
- raise Exception("argh")
-
- return self.provider[name]["class"]
--- a/iro/test_helpers/dbtestcase.py Sat Mar 24 00:02:42 2012 +0100
+++ b/iro/test_helpers/dbtestcase.py Sat Mar 24 00:07:40 2012 +0100
@@ -13,6 +13,8 @@
from iro.controller.pool import dbPool
+from .utils import DummyObserver
+
class DBTestCase(unittest.TestCase):
'''a TestCase with DB connection
you have to set self.session manually in setUp'''
@@ -22,8 +24,11 @@
def setUp(self):
md.setUp()
+ self.log = DummyObserver()
+ self.log.start()
def tearDown(self):
+ self.log.stop()
self.__cleanDB()
def session(self,autocommit=True):
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/iro/test_helpers/utils.py Sat Mar 24 00:07:40 2012 +0100
@@ -0,0 +1,18 @@
+from twisted.python import log
+
+class DummyObserver(object):
+ def __init__(self):
+ self.e=[]
+
+ def start(self):
+ log.addObserver(self.emit)
+
+ def stop(self):
+ log.removeObserver(self.emit)
+
+ def emit(self, eventDict):
+ self.e.append(eventDict)
+
+class DummyPool():
+ def run(self, f,*a,**k):
+ return f(*a,**k)
--- a/iro/tests/install.py Sat Mar 24 00:02:42 2012 +0100
+++ b/iro/tests/install.py Sat Mar 24 00:07:40 2012 +0100
@@ -1,28 +1,17 @@
#from mock import patch, Mock
from twisted.trial import unittest
-from twisted.python import log
from sqlalchemy import create_engine
+from sets import Set
+import io
import os
from iro import install
from iro import config
-from iro.model.schema import Base
-
+from iro.model.schema import Base, Offer
+from iro.model.utils import WithSession
+from iro.offer.provider import providers, Provider
from ..test_helpers.dbtestcase import md, SampleDatabase
-
-class DummyObserver(object):
- def __init__(self):
- self.e=[]
-
- def start(self):
- log.addObserver(self.emit)
-
- def stop(self):
- log.removeObserver(self.emit)
-
- def emit(self, eventDict):
- self.e.append(eventDict)
-
+from ..test_helpers.utils import DummyObserver
class TestInstallation(unittest.TestCase):
'''test install script'''
@@ -105,6 +94,70 @@
self.assertEqual(len(self.log.e),1)
self.assertEqual(self.log.e[0]['message'], ("iro.conf exists and will not be overwritten.",))
- def testCheck(self):
- pass
- testCheck.todo = "to implement"
+ def testGetAllRoutesNone(self):
+ config.main.dburl=md.dburl2
+ install.createDatabase()
+ self.assertEqual(install.getAllRoutes([]),{"orphand":Set(),"added":Set()})
+
+ def testGetAllRoutesOrphand(self):
+ config.main.dburl=md.dburl2
+ install.createDatabase()
+ self.engine = create_engine(md.dburl2)
+ with WithSession(self.engine,True) as session:
+ session.add(Offer(provider="p",route="r",typ="t",name="test"))
+ session.add(Offer(provider="p",route="r2",typ="t",name="test2"))
+ self.assertEqual(install.getAllRoutes([]),{"orphand":Set(["test","test2"]),"added":Set()})
+
+ def testGetAllRoutesAdded(self):
+ config.main.dburl=md.dburl2
+ install.createDatabase()
+ self.engine = create_engine(md.dburl2)
+ class TestProvider(Provider):
+ def __init__(self, name):
+ Provider.__init__(self, name, {"r":["1","2","3"]})
+ providers["test"]=TestProvider
+ sample_config = """[p]
+typ= test
+test= foo
+"""
+ config.configParser.readfp(io.BytesIO(sample_config))
+ self.assertEqual(install.getAllRoutes(["p"]),{"orphand":Set(),"added":Set(["p_r_1","p_r_2","p_r_3"])})
+
+ #test writing
+ self.assertEqual(install.getAllRoutes(["p"],True),{"orphand":Set(),"added":Set(["p_r_1","p_r_2","p_r_3"])})
+ with WithSession(self.engine,True) as session:
+ o = Set([i[0] for i in session.query(Offer.name).all()])
+ self.assertEqual(o,Set(["p_r_1","p_r_2","p_r_3"]))
+
+ #nothing to do anymore
+ self.assertEqual(install.getAllRoutes(["p"]),{"orphand":Set(),"added":Set()})
+
+ def testGetAllRoutesOaA(self):
+ config.main.dburl=md.dburl2
+ install.createDatabase()
+ self.engine = create_engine(md.dburl2)
+ class TestProvider(Provider):
+ def __init__(self, name):
+ Provider.__init__(self, name, {"r":["1","2","3"]})
+ providers["test"]=TestProvider
+ sample_config = """[p]
+typ= test
+test= foo
+"""
+ config.configParser.readfp(io.BytesIO(sample_config))
+
+ with WithSession(self.engine,True) as session:
+ session.add(Offer(provider="q",route="r",typ="t",name="test"))
+ session.add(Offer(provider="q",route="r2",typ="t",name="test2"))
+ session.add(Offer(provider="p",route="1",typ="r",name="foo"))
+ self.assertEqual(install.getAllRoutes(["p"]),{"orphand":Set(["test","test2"]),"added":Set(["p_r_2","p_r_3"])})
+
+ #test writing
+ self.assertEqual(install.getAllRoutes(["p"],True),{"orphand":Set(["test","test2"]),"added":Set(["p_r_2","p_r_3"])})
+ with WithSession(self.engine,True) as session:
+ o = Set([i[0] for i in session.query(Offer.name).all()])
+ self.assertEqual(o,Set(["test","test2","foo","p_r_2","p_r_3"]))
+
+ self.assertEqual(install.getAllRoutes(["p"]),{"orphand":Set(["test","test2"]),"added":Set()})
+
+
--- a/iro/tests/job.py Sat Mar 24 00:02:42 2012 +0100
+++ b/iro/tests/job.py Sat Mar 24 00:07:40 2012 +0100
@@ -16,25 +16,7 @@
from iro.validate import vInteger
from ..test_helpers.dbtestcase import DBTestCase
-
-class DummyPool():
- def run(self, f,*a,**k):
- return f(*a,**k)
-
-from twisted.python import log
-
-class DummyObserver(object):
- def __init__(self):
- self.e=[]
-
- def start(self):
- log.addObserver(self.emit)
-
- def stop(self):
- log.removeObserver(self.emit)
-
- def emit(self, eventDict):
- self.e.append(eventDict)
+from ..test_helpers.utils import DummyPool
class JobTestCase(DBTestCase):
def setUp(self):
@@ -70,6 +52,7 @@
self.assertEqual(j,[(job.dbjob,)])
self.assertEqual(exJobs[job.dbjob],job)
+ self.assertEqual(self.log.e[0]['message'], ("Job(%s) created."%job.dbjob,))
def testCreate2(self):
with self.session() as session:
@@ -114,8 +97,6 @@
class StatiTest(JobTestCase):
def setUp(self):
JobTestCase.setUp(self)
- self.log = DummyObserver()
- self.log.start()
with self.session() as session:
u = User(name='test',apikey='abcdef123456789')
@@ -130,7 +111,6 @@
self.job = exJobs.create(u, [Telnumber('123456789')], SMS('test'), [])
def tearDown(self):
- self.log.stop()
JobTestCase.tearDown(self)
@@ -138,7 +118,8 @@
self.job.setError(Task(Telnumber('123456789'),self),Exception("muhaha"))
errors = self.flushLoggedErrors(Exception)
self.assertEqual(len(errors), 1)
- self.assertEqual(self.log.e[0]['why'], "Error: Job(%s) to '0049123456789' failed."%self.job.dbjob)
+ self.assertEqual(self.log.e[1]['message'], ("Job(%s) status changed to: error."%self.job.dbjob,))
+ self.assertEqual(self.log.e[2]['why'], "Error: Job(%s) to '0049123456789' failed."%self.job.dbjob)
with self.session() as session:
u = session.merge(self.user)
@@ -150,7 +131,8 @@
status = Status(self.provider,"a")
self.job.setStatus(task, status)
- self.assertEqual(self.log.e[0]['message'], ("Job(%s) to '0049123456789' ended sucecessfully via bla:a."%self.job.dbjob,))
+ self.assertEqual(self.log.e[1]['message'], ("Job(%s) status changed to: sended."%self.job.dbjob,))
+ self.assertEqual(self.log.e[2]['message'], ("Job(%s) to '0049123456789' ended sucecessfully via bla:a."%self.job.dbjob,))
with self.session() as session:
u = session.merge(self.user)
--- a/iro/tests/model_validate.py Sat Mar 24 00:02:42 2012 +0100
+++ b/iro/tests/model_validate.py Sat Mar 24 00:07:40 2012 +0100
@@ -5,10 +5,7 @@
from iro.error import ValidateException
from ..test_helpers.dbtestcase import DBTestCase
-
-class DummyPool():
- def run(self, f,*a,**k):
- return f(*a,**k)
+from ..test_helpers.utils import DummyPool
class ModelVaidatorTest(DBTestCase):
"""tests for the model vaidators"""
--- a/iro/tests/offer_integrated.py Sat Mar 24 00:02:42 2012 +0100
+++ b/iro/tests/offer_integrated.py Sat Mar 24 00:07:40 2012 +0100
@@ -15,33 +15,14 @@
from iro.offer import Smstrade, SMTP, Offer
from iro.offer.smstrade import SmstradeException, StatusCode
+from iro.error import NoRouteForTask
from ..test_helpers.dbtestcase import DBTestCase
-
-class DummyPool():
- def run(self, f,*a,**k):
- return f(*a,**k)
+from ..test_helpers.utils import DummyPool
def run( f,*a,**k):
return f(*a,**k)
-from twisted.python import log
-
-class DummyObserver(object):
- def __init__(self):
- self.e=[]
-
- def start(self):
- log.addObserver(self.emit)
-
- def stop(self):
- log.removeObserver(self.emit)
-
- def emit(self, eventDict):
- self.e.append(eventDict)
-
-
-
class IntegratedOfferTests(DBTestCase):
def setUp(self):
DBTestCase.setUp(self)
@@ -51,11 +32,7 @@
self.taskPool = taskPool.run
taskPool.run = run
- self.log = DummyObserver()
- self.log.start()
-
def tearDown(self):
- self.log.stop()
exJobs.clear()
data.pool = self.pool
self.pool = None
@@ -89,7 +66,7 @@
t = Task(Telnumber("0123456789"),j)
yield t.start()
- self.assertEqual(self.log.e[0]['message'], ("Job(%s) to '0049123456789' ended sucecessfully via bla:basic."%j.dbjob,))
+ self.assertEqual(self.log.e[2]['message'], ("Job(%s) to '0049123456789' ended sucecessfully via bla:basic."%j.dbjob,))
with self.session() as session:
u = session.merge(u)
@@ -132,10 +109,13 @@
errors = self.flushLoggedErrors(SmstradeException)
self.assertEqual(len(errors), 1)
- self.assertEqual(self.log.e[0]['why'], "Error: Job(%s) to '0049123456789' failed."%j.dbjob)
+ errors = self.flushLoggedErrors(NoRouteForTask)
+ self.assertEqual(len(errors), 1)
+ self.assertEqual(self.log.e[1]['why'], "Job(%s): Send to '0049123456789' failed via 's'"%j.dbjob)
+ self.assertEqual(self.log.e[3]['why'], "Error: Job(%s) to '0049123456789' failed."%j.dbjob)
self.assertEqual(t.error, True)
- self.assertEqual(str(t.status.value),str(SmstradeException(StatusCode(703))))
+ self.assertEqual(str(self.log.e[1]['failure'].value),str(SmstradeException(StatusCode(703))))
with self.session() as session:
u = session.merge(u)
@@ -166,7 +146,7 @@
t = Task("t@test.de",j)
yield t.start()
- self.assertEqual(self.log.e[0]['message'], ("Job(%s) to 't@test.de' ended sucecessfully via bla:None."%j.dbjob,))
+ self.assertEqual(self.log.e[2]['message'], ("Job(%s) to 't@test.de' ended sucecessfully via bla:None."%j.dbjob,))
with self.session() as session:
u = session.merge(u)
@@ -199,12 +179,14 @@
t = Task("t@test.de",j)
yield t.start()
+ errors = self.flushLoggedErrors(NoRouteForTask)
+ self.assertEqual(len(errors), 1)
errors = self.flushLoggedErrors(IOError)
self.assertEqual(len(errors), 1)
- self.assertEqual(self.log.e[0]['why'], "Error: Job(%s) to 't@test.de' failed."%j.dbjob
-)
+ self.assertEqual(self.log.e[1]['why'], "Job(%s): Send to 't@test.de' failed via 's'"%j.dbjob)
+ self.assertEqual(self.log.e[3]['why'], "Error: Job(%s) to 't@test.de' failed."%j.dbjob)
self.assertEqual(t.error, True)
- self.assertEqual(str(t.status.value),str(IOError(111,"Connection refused")))
+ self.assertEqual(str(self.log.e[1]['failure'].value),str(IOError(111,"Connection refused")))
with self.session() as session:
u = session.merge(u)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/iro/tests/pool.py Sat Mar 24 00:07:40 2012 +0100
@@ -0,0 +1,21 @@
+from twisted.trial import unittest
+from mock import Mock
+import copy
+
+from iro.controller import pool
+
+class PoolTestCase(unittest.TestCase):
+
+ def setUp(self):
+ self._pools = copy.copy(pool.pools)
+
+ def tearDown(self):
+ del pool.pools[:]
+ pool.pools.extend(self._pools)
+
+ def testStartPool(self):
+ del pool.pools[:]
+ pool.pools.extend([Mock(),Mock()])
+ pool.startPool("blafo")
+ for i in pool.pools:
+ i.start.assert_called_with("blafo")
--- a/iro/tests/task.py Sat Mar 24 00:02:42 2012 +0100
+++ b/iro/tests/task.py Sat Mar 24 00:07:40 2012 +0100
@@ -113,6 +113,45 @@
d.addCallback(c)
return d
+ def testChaining(self):
+ with self.session() as session:
+ u = User(name='test',apikey='abcdef123456789')
+ session.add(u)
+ o=DBOffer(name="test", provider="bla", route="basic", typ="sms")
+ u.rights.append(Userright(o))
+ o=DBOffer(name="test2", provider="bla", route="basic2", typ="sms")
+ u.rights.append(Userright(o))
+
+ p=Provider(name="p", typs={"sms":["basic","basic2"]})
+ def send(typ,route,recipient,message):
+ if route=="basic":
+ raise Exception("oh my god an exception")
+ return Status(p,route)
+ p.send=send
+ offers["test"] = Offer("test",provider=p, route="basic", typ="sms")
+ offers["test2"] = Offer("test2",provider=p, route="basic2", typ="sms")
+
+ def c(exjob):
+ task = Task(Telnumber('123456789'), exjob)
+ task.d = Deferred()
+ task.d.addCallback(stat, task)
+ task._run()
+ return task.d
+
+ def stat(status, task):
+ errors = self.flushLoggedErrors(Exception)
+ self.assertEqual(len(errors), 1)
+ self.assertEqual(self.log.e[1]['why'], "Job(%s): Send to '0049123456789' failed via 'test'"% task.job.dbjob)
+ self.assertIsInstance(status, Status)
+ self.assertEqual(status.provider, p)
+ self.assertEqual(status.route, "basic2")
+
+ d = exJobs.create(u, [Telnumber('123456789')], SMS('test'), ['test','test2'])
+ d.addCallback(c)
+ return d
+
+
+
def testSetStatus(self):
task=Task(Telnumber('123456789'), None)
self.assertEqual(task.status,None)
--- a/iro/tests/viewinterface.py Sat Mar 24 00:02:42 2012 +0100
+++ b/iro/tests/viewinterface.py Sat Mar 24 00:07:40 2012 +0100
@@ -1,6 +1,7 @@
from twisted.internet.defer import inlineCallbacks
from datetime import datetime
from Queue import deque
+from mock import patch
from iro.model.schema import User, Offer, Userright, Job, Message
from iro.controller.viewinterface import Interface
@@ -14,10 +15,7 @@
import iro.error as IroError
from ..test_helpers.dbtestcase import DBTestCase
-
-class DummyPool():
- def run(self, f,*a,**k):
- return f(*a,**k)
+from ..test_helpers.utils import DummyPool
class ViewInterfaceTest(DBTestCase):
"""tests for the xmlrpc interface"""
@@ -214,8 +212,10 @@
self.assertEqual(taskPool.pool.q.qsize(),1)
+ @patch("iro.model.message.formatdate")
@inlineCallbacks
- def testMail(self):
+ def testMail(self,mock_f):
+ mock_f.return_value="Wed, 21 Mar 2012 17:16:11 +0100"
with self.session() as session:
u = User(name='test',apikey='abcdef123456789')
o = Offer(name='loc',provider="localhost",route="",typ="mail")
@@ -231,8 +231,10 @@
self.assertEqual(exJob.message,Mail("sub",'hey body!','frm@t.de'))
self.assertEqual(taskPool.pool.q.qsize(),1)
+ @patch("iro.model.message.formatdate")
@inlineCallbacks
- def testMailFrmNone(self):
+ def testMailFrmNone(self,mock_f):
+ mock_f.return_value="Wed, 21 Mar 2012 17:16:11 +0100"
with self.session() as session:
u = User(name='test',apikey='abcdef123456789')
o = Offer(name='loc',provider="localhost",route="",typ="mail")
--- a/iro/tests/xmlrpc_client.py Sat Mar 24 00:02:42 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-from multiprocessing.pool import ThreadPool
-import xmlrpclib
-import timeit
-
-
-def x(i):
- xmlrpclib.ServerProxy('http://192.168.56.101:7080/RPC2').status('abcdef123456789')
-
-pool=ThreadPool(50)
-
-print min(timeit.repeat(lambda:pool.map(x,range(51)),number=1,repeat=1))
-
--- a/iro/worker.py Sat Mar 24 00:02:42 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-# -*- coding: utf-8 -*-
-# Worker code
-
-from multiprocessing import Process
-import logging
-logger = logging.getLogger("iro.worker")
-
-class Worker(Process):
- def __init__(self,queue):
- Process.__init__(self)
- self.queue=queue
-
- def run(self):
- logger.info('Workerprocess läuft nun...')
- indifier=0
- while 1:
- job=self.queue.get()
- if job is None:
- break # reached end of queue
- indifier+=1
- logger.info('ein neuer Job(%d)' %(indifier))
- try:
- job.start(indifier)
- logger.info('Job(%d) fertig ;)'%(indifier))
- except:
- job.setStatus("error")
- logger.exception('Job(%d) fehlgeschlagen :('%(indifier))
-
--- a/iro/xmlrpc/AuthentificateXMLRPCServer.py Sat Mar 24 00:02:42 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-# Server code
-import SimpleXMLRPCServer
-import string,base64
-
-class AuthentificateXMLRPCRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
- def do_POST(self):
- try:
- header = self.headers['Authorization']
- type, user_passwd = header.split()
- username, password = string.split(base64.decodestring(user_passwd), ':')
- if self.testUser(username,password):
- SimpleXMLRPCServer.SimpleXMLRPCRequestHandler.do_POST(self)
- else:
- self.report_error(401)
- except:
- self.report_error(401)
-
- def report_error (self,code):
- '''
- Send back an errorcode
- '''
- #it is important to read out the complete sended request ,
- # but throw the data away, because an error should be send back
- try:
- max_chunk_size = 10*1024*1024
- size_remaining = int(self.headers["content-length"])
- while size_remaining:
- chunk_size = min(size_remaining, max_chunk_size)
- size_remaining -= len(self.rfile.read(chunk_size))
- except:
- pass
-
- #now just send the error back
- special_errors={401:self.report_401,
- 404:self.report_404}
- if special_errors.has_key(code):
- special_errors[code]()
- else:
- self.send_response(code)
- self.end_headers()
- self.connection.shutdown(1)
-
- def report_401(self):
- self.send_response(401)
- self.send_header("WWW-Authenticate", 'Basic realm="%s"'% self.server.relam)
- response = 'Unauthorised'
- self.send_header("Content-type", "text/plain")
- self.send_header("Content-length", str(len(response)))
- self.end_headers()
- self.wfile.write(response)
- # shut down the connection
- self.wfile.flush()
- self.connection.shutdown(1)
-
- def testUser(self,username,password):
- """
- Function for testing authentification
- """
- if username=="test" and password=="test":
- return True
-
- return False
-
-
-
-def test():
- server = SimpleXMLRPCServer.SimpleXMLRPCServer(("localhost", 8000),AuthentificateXMLRPCRequestHandler)
- server.relam="xmlrpc"
- server.register_introspection_functions()
- server.register_function(lambda x: x*x, 'square')
- server.serve_forever()
-
-if __name__ == '__main__':
- test()
-
-
--- a/iro/xmlrpc/SecureAuthentificateXMLRPCServer.py Sat Mar 24 00:02:42 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-# Server code
-import AuthentificateXMLRPCServer
-import SecureXMLRPCServer
-
-class SecureAuthentificateXMLRPCRequestHandler(SecureXMLRPCServer.SecureXMLRPCRequestHandler,AuthentificateXMLRPCServer.AuthentificateXMLRPCRequestHandler):
- def do_POST(self):
- AuthentificateXMLRPCServer.AuthentificateXMLRPCRequestHandler.do_POST(self)
-
-
-def test():
- server = SecureXMLRPCServer.SecureXMLRPCServer(("localhost", 8000),requestHandler=SecureAuthentificateXMLRPCRequestHandler,certificate="./certs/test.cert.pem",privatekey="./certs/test.key.pem")
- server.relam="xmlrpc"
- server.register_introspection_functions()
- server.register_function(lambda x: x*x, 'square')
- server.serve_forever()
-
-if __name__ == '__main__':
- test()
-
-
--- a/iro/xmlrpc/SecureUserdbXMLRPCServer.py Sat Mar 24 00:02:42 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-from SecureAuthentificateXMLRPCServer import SecureAuthentificateXMLRPCRequestHandler
-from SecureXMLRPCServer import SecureXMLRPCServer
-import os, hashlib
-
-class UserDB:
- '''
- class for managing all xmlrpc users
- - each user is indyfied via a hash value, which is created out of the username + password
- '''
- def __init__(self,userClass, userlist,jobqueue):
- self.salt=os.urandom(20)
- self.jobqueue=jobqueue
- self.userClass=userClass
- self.userlist={}
- for user in userlist:
- self.createUser(user)
-
- def createHash(self,user):
- """
- returns a hash out of username and the password and self.salt
- user is a directory with two keys: username and password
- """
- m=hashlib.sha512()
- m.update(user["name"])
- m.update(self.salt)
- m.update(user["password"])
- return m.hexdigest()
-
- def createUser(self,user):
- self.userlist[self.createHash(user)]=self.userClass(user["name"],self.jobqueue)
-
- def __getitem__(self,key):
- return self.userlist[key]
-
-
-class SecureAuthentificateXMLRPCRequestHandler2(SecureAuthentificateXMLRPCRequestHandler):
- def testUser(self,username,password):
- """
- Function for testing authentification
- """
- return self.server.activateUser(username,password)
-
-class SecureUserDBXMLRPCServer(SecureXMLRPCServer):
- def __init__(self, addr, userdb,
- requestHandler=SecureAuthentificateXMLRPCRequestHandler2,
- certificate="server.cert", privatekey="server.pem",
- logRequests=1):
- SecureXMLRPCServer.__init__(self, addr, requestHandler, certificate, privatekey, logRequests)
- self.relam="xmlrpc"
- self.userdb=userdb
-
- def activateUser(self,username,password):
- """
- Function is executed, if someone ant to login
- -searches for a regular user in the userdb and then put all methods of the user as XMLRPC
- returns weather a user was found or not
- """
- try:
- user = self.userdb[self.userdb.createHash({"name":username,"password":password})]
- self.register_instance(user)
- return True
- except KeyError:
- return False
--- a/iro/xmlrpc/SecureXMLRPCServer.py Sat Mar 24 00:02:42 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-"""
-SecureXMLRPCServer module using pyOpenSSL 0.5
-Written 0907.2002
-by Michal Wallace
-http://www.sabren.net/
-
-This acts exactly like SimpleXMLRPCServer
-from the standard python library, but
-uses secure connections. The technique
-and classes should work for any SocketServer
-style server. However, the code has not
-been extensively tested.
-
-This code is in the public domain.
-It is provided AS-IS WITH NO WARRANTY WHATSOEVER.
-"""
-import SocketServer
-import os, socket
-import SimpleXMLRPCServer
-from OpenSSL import SSL
-
-class SSLWrapper:
- """
- This whole class exists just to filter out a parameter
- passed in to the shutdown() method in SimpleXMLRPC.doPOST()
- """
- def __init__(self, conn):
- """
- Connection is not yet a new-style class,
- so I'm making a proxy instead of subclassing.
- """
- self.__dict__["conn"] = conn
- def __getattr__(self,name):
- return getattr(self.__dict__["conn"], name)
- def __setattr__(self,name, value):
- setattr(self.__dict__["conn"], name, value)
- def shutdown(self, how=1):
- """
- SimpleXMLRpcServer.doPOST calls shutdown(1),
- and Connection.shutdown() doesn't take
- an argument. So we just discard the argument.
- """
- self.__dict__["conn"].shutdown()
- def accept(self):
- """
- This is the other part of the shutdown() workaround.
- Since servers create new sockets, we have to infect
- them with our magic. :)
- """
- c, a = self.__dict__["conn"].accept()
- return (SSLWrapper(c), a)
-
-
-
-class SecureTCPServer(SocketServer.TCPServer):
- """
- Just like TCPServer, but use a socket.
- This really ought to let you specify the key and certificate files.
- """
- def __init__(self, server_address, RequestHandlerClass,certificate,privatekey):
- SocketServer.BaseServer.__init__(self, server_address, RequestHandlerClass)
-
- ## Same as normal, but make it secure:
- ctx = SSL.Context(SSL.SSLv23_METHOD)
- ctx.set_options(SSL.OP_NO_SSLv2)
-
- ctx.use_privatekey_file (privatekey)
- ctx.use_certificate_file(certificate)
-
- self.socket = SSLWrapper(SSL.Connection(ctx, socket.socket(self.address_family,
- self.socket_type)))
- self.server_bind()
- self.server_activate()
-
-
-class SecureXMLRPCRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
- def setup(self):
- """
- We need to use socket._fileobject Because SSL.Connection
- doesn't have a 'dup'. Not exactly sure WHY this is, but
- this is backed up by comments in socket.py and SSL/connection.c
- """
- self.connection = self.request # for doPOST
- self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
- self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)
-
-
-class SecureXMLRPCServer(SimpleXMLRPCServer.SimpleXMLRPCServer, SecureTCPServer):
- def __init__(self, addr,
- requestHandler=SecureXMLRPCRequestHandler,
- certificate="server.cert",privatekey="server.pem",
- logRequests=1):
- """
- This is the exact same code as SimpleXMLRPCServer.__init__
- except it calls SecureTCPServer.__init__ instead of plain
- old TCPServer.__init__
- """
- self.funcs = {}
- self.logRequests = logRequests
- self.instance = None
- SimpleXMLRPCServer.SimpleXMLRPCDispatcher.__init__(self,False,None)
- SecureTCPServer.__init__(self, addr, requestHandler,certificate=certificate,privatekey=privatekey)
-
-
-def test():
- server = SecureXMLRPCServer.SecureXMLRPCServer(("localhost", 8000),requestHandler=SecureXMLRPCRequestHandler,certificate="./certs/test.cert.pem",privatekey="./certs/test.key.pem")
- server.register_introspection_functions()
- server.register_function(lambda x: x*x, 'square')
- server.serve_forever()
-
-if __name__ == '__main__':
- test()
-
--- a/iro/xmlrpc/__init__.py Sat Mar 24 00:02:42 2012 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-from AuthentificateXMLRPCServer import AuthentificateXMLRPCRequestHandler
-from SecureXMLRPCServer import SecureXMLRPCRequestHandler, SecureXMLRPCServer
-from SecureAuthentificateXMLRPCServer import SecureAuthentificateXMLRPCRequestHandler
-from SecureUserdbXMLRPCServer import SecureUserDBXMLRPCServer, UserDB