Browse files

Merge remote-tracking branch 'origin/master'

Conflicts:
	core.py
	core_test.py
  • Loading branch information...
2 parents 932e1fe + f735b7a commit 5e54a059d886033b799c3ab3dfb405508b6d0b9d oau committed Dec 15, 2012
Showing with 200 additions and 175 deletions.
  1. +19 −17 README.md
  2. +2 −1 config.py.default
  3. +118 −111 core.py
  4. +14 −11 core_test.py
  5. +25 −22 smskrupp
  6. +22 −13 web.py
View
36 README.md
@@ -1,6 +1,20 @@
# smskrupp
-A project using [gammu](https://github.com/gammu/gammu) to handle sms lists.
+smskrupp **implements SMS lists** on top of [gammu](https://github.com/gammu/gammu). Gammu does all the lower-level talking to the modem.
+
+It has a command-line interface and a Web interface for list management.
+
+## Usage
+
+Use the `smskrupp` command to manage groups:
+
+ $ ./smskrupp add-group test t
+ $ ./smskrupp add-member 0731234567 member1 test
+ $ ./smskrupp add-member 0731234568 member2 test
+ $ ./smskrupp set-sender 0731234567 test
+ $ ./smskrupp list-members test
+
+Now if you have gammu-smsd set up correctly you should be able to send a message from 0731234567 to the phone you've setup with gammu and it will deliver to all members in the group.
## Setup
@@ -14,32 +28,20 @@ If you want the webapp you also need:
# apt-get install python-bcrypt python-flask
-Setting up the db:
+Setting up the sqlite database:
- $ cat sql/*.sql | sqlite3 smskrupp.db
+ $ cat sql/*.sql | sqlite3 smskrupp.db && cat sql/*.sql | sqlite3 smskrupp-test.db
Create the config file:
$ cp config.py.default config.py
-Edit the config file so it points to the correct places.
+Edit the config file so it points to the correct locations.
For gammu to work you also need a gammu-smsdrc, there is an example file in the doc/ directory.
-## Usage
-
-use smskrupp command to manage groups:
-
- $ smskrupp add-group test t
- $ smskrupp add-member 0731234567 member1 test
- $ smskrupp add-member 0731234568 member2 test
- $ smskrupp set-sender 0731234567 test
- $ smskrupp list-members test
-
-Now if you have gammu-smsd setup correctly you should be able to send a message from 0731234567 to the phone you've setup with gammu and it will deliver to all members in the group.
-
## Tests
-If your config.py points to a test-db and a test-smsdrc, simply run
+If your config.py points to a test-db and a test-smsdrc -- this is the default configuration -- simply run:
$ nosetests
View
3 config.py.default
@@ -1,8 +1,9 @@
class Config:
db = 'smskrupp.db'
smsdrc = '/etc/gammu-smsdrc'
- test_db = 'tmp.db'
+ test_db = 'smskrupp-test.db'
test_smsdrc = 'test-gammu-smsdrc'
+ send_prefix='#'
admin_prefix='/'
log = 'smskrupp.log'
default_phone = 'phone1'
View
229 core.py
@@ -2,27 +2,27 @@
from config import config
import sqlite3
-import gammu.smsd
from time import strftime, localtime
-import bcrypt
+
def normalize_number(number):
if number.startswith('07'):
- return '+46'+number[1:]
+ return '+46' + number[1:]
elif number.startswith('0046'):
- return '+'+number[2:]
+ return '+' + number[2:]
elif number.startswith('+46'):
return number
return None
+
class Data:
def __init__(self):
self.conn = sqlite3.connect(config.db)
self.cursor = self.conn.cursor()
def setup_db(self):
'''Creates the database tables.'''
- with open('sql/smskrupp.sql','r') as f:
+ with open('sql/smskrupp.sql', 'r') as f:
self.cursor.executescript(f.read())
self.conn.commit()
@@ -34,37 +34,37 @@ def add_number(self, number, alias, group_id):
c = self.cursor
if alias == None:
base = "noname"
- c.execute("select alias from qq_groupMembers "+
+ c.execute("select alias from qq_groupMembers " +
"where alias like ? order by alias ",
- (base+'%',))
+ (base + '%',))
max_num = 0
for row in c:
num = row[0][len(base):]
if num.isdigit() and int(num) > max_num:
max_num = int(num)
- alias = base+str(max_num+1)
+ alias = base + str(max_num + 1)
- c.execute("insert or ignore into qq_groupMembers "+
- "(number, groupId, alias) "+
+ c.execute("insert or ignore into qq_groupMembers " +
+ "(number, groupId, alias) " +
"values (?,?,?)",
(number, group_id, alias))
- c.execute("update qq_groupMembers set alias=? "+
+ c.execute("update qq_groupMembers set alias=? " +
"where number=? and groupId=?",
(alias, number, group_id))
self.conn.commit()
- return self.get_member_id(number,group_id)
+ return self.get_member_id(number, group_id)
def set_member_info(self, member_id, **kwargs):
c = self.cursor
if 'sender' in kwargs:
c.execute("update qq_groupMembers set sender=? where id=?",
- (kwargs['sender'],member_id))
+ (kwargs['sender'], member_id))
if 'admin' in kwargs:
c.execute("update qq_groupMembers set admin=? where id=?",
- (kwargs['admin'],member_id))
+ (kwargs['admin'], member_id))
if 'alias' in kwargs:
c.execute("update qq_groupMembers set alias=? where id=?",
- (kwargs['alias'],member_id))
+ (kwargs['alias'], member_id))
self.conn.commit()
def remove_number(self, member_id=None, number=None, group_id=None):
@@ -80,9 +80,9 @@ def add_group(self, name, keyword, phone):
''' create a group and return id of the created group
'''
c = self.cursor
- c.execute("insert into qq_groups (name,keyword,phone) "+
+ c.execute("insert into qq_groups (name,keyword,phone) " +
"values (?,?,?)",
- (name,keyword,phone))
+ (name, keyword, phone))
self.conn.commit()
c.execute('select id from qq_groups where name=?', (name,))
group_id = None
@@ -104,24 +104,24 @@ def remove_group(self, gid):
def get_group_senders(self, group_id):
c = self.cursor
- c.execute('select id, number, alias from qq_groupMembers '+
+ c.execute('select id, number, alias from qq_groupMembers ' +
'where groupId=? and sender=1', (group_id,))
- return [{'id':row[0],'number':row[1],'alias':row[2]} for row in c]
+ return [{'id': row[0], 'number': row[1], 'alias': row[2]} for row in c]
def get_group_admins(self, group_id):
c = self.cursor
- c.execute('select id,number,alias from qq_groupMembers '+
+ c.execute('select id,number,alias from qq_groupMembers ' +
'where groupId=? and admin=1', (group_id,))
- return [{'id':row[0],'number':row[1],'alias':row[2]} for row in c]
+ return [{'id': row[0], 'number': row[1], 'alias': row[2]} for row in c]
def get_group_members(self, group_id):
''' return array of dicts describing members (id, number, alias, sender, admin)
'''
c = self.cursor
c.execute('select id,number,alias,sender,admin from qq_groupMembers '+
'where groupId=?',
- (group_id,))
- return [{'id':row[0], 'number':row[1], 'alias':row[2], 'sender':(row[3]==1),
+ (group_id, ))
+ return [{'id': row[0], 'number': row[1], 'alias': row[2], 'sender': (row[3] ==1 ),
'admin':(row[4]==1)} for row in c]
def get_groups(self, phone=None, number=None):
@@ -132,11 +132,11 @@ def get_groups(self, phone=None, number=None):
c.execute('select g.id, g.name, g.keyword, g.phone from qq_groupMembers m '
+'join qq_groups g on g.id = m.groupId '
+'where m.number=? and g.phone=? order by g.name asc',
- (number,phone))
+ (number, phone))
elif number:
c.execute('select g.id, g.name, g.keyword, g.phone from qq_groupMembers m '
- +'join qq_groups g on g.id = m.groupId '
- +'where m.number=? order by g.name asc',
+ + 'join qq_groups g on g.id = m.groupId '
+ + 'where m.number=? order by g.name asc',
(number,))
elif phone:
c.execute('select id,name, keyword, phone from qq_groups where phone=? order by name asc',
@@ -151,13 +151,13 @@ def get_send_groups(self, sender, phone=None):
c = self.cursor
if phone:
c.execute('select g.id, g.name, g.keyword, g.phone from qq_groupMembers m '
- +'join qq_groups g on g.id = m.groupId '
- +'where m.number=? and g.phone=? and m.sender=1 order by g.name asc',
- (sender,phone))
+ + 'join qq_groups g on g.id = m.groupId '
+ + 'where m.number=? and g.phone=? and m.sender=1 order by g.name asc',
+ (sender, phone))
else:
c.execute('select g.id, g.name, g.keyword, g.phone from qq_groupMembers m '
- +'join qq_groups g on g.id = m.groupId '
- +'where m.number=? and m.sender=1 order by g.name asc',
+ + 'join qq_groups g on g.id = m.groupId '
+ + 'where m.number=? and m.sender=1 order by g.name asc',
(sender,))
return [{'id':row[0], 'name':row[1], 'keyword':row[2], 'phone':row[3]} for row in c]
@@ -167,17 +167,17 @@ def get_admin_groups(self, sender, phone=None):
c = self.cursor
if phone:
c.execute('select g.id, g.name, g.keyword, g.phone from qq_groupMembers m '
- +'join qq_groups g on g.id = m.groupId '
- +'where m.number=? and g.phone=? and m.admin=1 order by g.name asc',
- (sender,phone))
+ + 'join qq_groups g on g.id = m.groupId '
+ + 'where m.number=? and g.phone=? and m.admin=1 order by g.name asc',
+ (sender, phone))
else:
c.execute('select g.id, g.name, g.keyword, g.phone from qq_groupMembers m '
- +'join qq_groups g on g.id = m.groupId '
- +'where m.number=? and m.admin=1 order by g.name asc',
+ + 'join qq_groups g on g.id = m.groupId '
+ + 'where m.number=? and m.admin=1 order by g.name asc',
(sender,))
return [{'id':row[0], 'name':row[1], 'keyword':row[2], 'phone':row[3]} for row in c]
- def get_group_id(self,name):
+ def get_group_id(self, name):
c = self.cursor
c.execute('select id,name from qq_groups where name=?', (name,))
x = c.fetchone()
@@ -208,11 +208,11 @@ def get_member_ids(self, number):
def get_member_info(self, member_id):
c = self.cursor
c.execute('select m.id,m.number,m.alias,m.groupId,g.name from qq_groupMembers m '
- +'left join qq_groups g on g.id = m.groupId where m.id=?',
+ + 'left join qq_groups g on g.id = m.groupId where m.id=?',
(member_id,))
x = c.fetchone()
if x:
- return {'id': x[0], 'number': x[1], 'alias': x[2], 'groupId':x[3], 'groupName':x[4]}
+ return {'id': x[0], 'number': x[1], 'alias': x[2], 'groupId': x[3], 'groupName': x[4]}
return None
def _calculate_udh_part(self, udh):
@@ -222,51 +222,51 @@ def _calculate_udh_part(self, udh):
i = 1
while i <= length:
# parse one IEI
- iei_id = int(udh[i*2:i*2+2], 16)
+ iei_id = int(udh[i * 2: i * 2 + 2], 16)
i += 1
- iei_len = int(udh[i*2:i*2+2], 16)
+ iei_len = int(udh[i * 2: i * 2 + 2], 16)
if not iei_id == 0:
# not concatenation iei
i += iei_len
continue
i += 1
- ref = int(udh[i*2:i*2+2], 16)
+ ref = int(udh[i * 2: i * 2 + 2], 16)
i += 1
- num_parts = int(udh[i*2:i*2+2], 16)
+ num_parts = int(udh[i * 2: i * 2 + 2], 16)
i += 1
- part = int(udh[i*2:i*2+2], 16)
- return part,num_parts,ref
+ part = int(udh[i * 2: i * 2 + 2], 16)
+ return part, num_parts, ref
def get_unprocessed(self):
c = self.cursor
- c.execute("select ID,SenderNumber,RecipientID,TextDecoded,UDH "+
+ c.execute("select ID,SenderNumber,RecipientID,TextDecoded,UDH " +
"from inbox where Processed='false'")
parts = {}
ret = []
for row in c:
- i,src,phone,text,udh = row
+ i, src, phone, text, udh = row
x = self._calculate_udh_part(udh)
if x:
- part,num_parts,ref = x
- key = src+'-'+str(ref)
+ part, num_parts, ref = x
+ key = src + '-' + str(ref)
if not key in parts:
- parts[key] = src,phone,[],[]
- parts[key][2].append((part,text))
+ parts[key] = src, phone, [], []
+ parts[key][2].append((part, text))
parts[key][3].append(i)
if len(parts[key][2]) == num_parts:
# found all parts
- tot_text = "".join(map(lambda x: x[1], sorted(parts[key][2], key = lambda x: x[0])))
- ret.append({'ids':parts[key][3], 'src':src, 'phone':phone, 'text':tot_text})
+ tot_text = "".join(map(lambda x: x[1], sorted(parts[key][2], key=lambda x: x[0])))
+ ret.append({'ids': parts[key][3], 'src': src, 'phone': phone, 'text': tot_text})
del parts[key]
else:
# single part
- ret.append({'ids':[i], 'src':src, 'phone':phone, 'text':text})
+ ret.append({'ids': [i], 'src': src, 'phone': phone, 'text': text})
return ret
def set_processed(self, msgId, status='true'):
c = self.cursor
- c.execute("update inbox set Processed=? where ID=?", (status,msgId))
+ c.execute("update inbox set Processed=? where ID=?", (status, msgId))
self.conn.commit()
def fake_incoming(self, src, phoneId, msg):
@@ -288,39 +288,40 @@ def cleanup(self):
if self.conn:
self.conn.close()
self.conn = None
-
+
def add_webuser(self, username, pw, privilege):
+ import bcrypt
c = self.cursor
- h = bcrypt.hashpw(pw,bcrypt.gensalt())
+ h = bcrypt.hashpw(pw, bcrypt.gensalt())
c.execute('insert into qq_webUsers (username,hash,privilege) values (?,?,?)',
- (username,h,privilege))
+ (username, h, privilege))
self.conn.commit()
def get_webusers(self):
c = self.cursor
c.execute('select u.id,u.username,u.privilege,g.id,g.name from qq_webUsers u '
- +'left join qq_webUserGroups wg on wg.userId = u.id '
- +'left join qq_groups g on g.id = wg.groupId '
- +'order by u.id')
+ + 'left join qq_webUserGroups wg on wg.userId = u.id '
+ + 'left join qq_groups g on g.id = wg.groupId '
+ + 'order by u.id')
ret = []
seen = []
for row in c:
if row[0] in seen:
- ret[-1]['groups'].append({'group_id':row[3],'group_name':row[4]})
+ ret[-1]['groups'].append({'group_id': row[3], 'group_name': row[4]})
else:
seen.append(row[0])
- ret.append({'user_id':row[0],'username':row[1],'privilege':row[2],'groups':[]})
+ ret.append({'user_id': row[0], 'username': row[1], 'privilege': row[2], 'groups': []})
if row[3]:
- ret[-1]['groups'].append({'group_id':row[3],'group_name':row[4]})
+ ret[-1]['groups'].append({'group_id': row[3], 'group_name': row[4]})
return ret
def get_webuser_groups(self, webuser_id):
c = self.cursor
c.execute('select groupId,name,keyword from qq_webUserGroups wg '
- +'left join qq_groups g on g.id=wg.groupId where userId=?',
+ + 'left join qq_groups g on g.id=wg.groupId where userId=?',
(webuser_id,))
- return [{'id':row[0],'name':row[1], 'keyword':row[2]} for row in c]
+ return [{'id': row[0], 'name': row[1], 'keyword': row[2]} for row in c]
def set_webuser_group(self, webuser_id, group_id):
c = self.cursor
@@ -343,10 +344,11 @@ def remove_webuser_group(self, webuser_id, group_id):
self.conn.commit()
def set_webuser_pw(self, user_id, pw):
- h = bcrypt.hashpw(pw,bcrypt.gensalt())
+ import bcrypt
+ h = bcrypt.hashpw(pw, bcrypt.gensalt())
c = self.cursor
c.execute('update qq_webUsers set hash=? where id=?',
- (h,user_id))
+ (h, user_id))
self.conn.commit()
def check_webuser_login(self, username, password):
@@ -355,10 +357,12 @@ def check_webuser_login(self, username, password):
(username,))
row = c.fetchone()
if row:
+ import bcrypt
hashed = row[1]
if bcrypt.hashpw(password, hashed) == hashed:
- return row[3],row[2]
- return 0,0
+ return row[3], row[2]
+ return 0, 0
+
def increment_sent_stats(self, group_id):
day = strftime("%Y-%m-%d %H:%M:%S", localtime())
@@ -384,14 +388,14 @@ def cleanup(self):
def _log(self, text):
with open(config.log, "a") as log:
t = strftime("%Y-%m-%d %H:%M:%S", localtime())
- log.write("[%s] [doer] %s\n"%(t,text.encode('utf-8')));
+ log.write("[%s] [doer] %s\n" % (t, text.encode('utf-8')))
def _parse_action(self, src, phone, orig_msg):
groups = self.data.get_groups(phone=phone, number=src)
send_groups = self.data.get_send_groups(src, phone=phone)
lmsg = orig_msg.lower().strip()
if lmsg == 'stop' or lmsg == 'stopp':
- return {'action':'stop', 'groups':groups}
+ return {'action': 'stop', 'groups': groups}
if lmsg.startswith(config.admin_prefix):
admin_cmd = lmsg[len(config.admin_prefix):]
first_word = admin_cmd.split(" ")[0]
@@ -407,18 +411,17 @@ def _parse_action(self, src, phone, orig_msg):
if not group:
# no keyword
if len(groups) == 1 and admin_cmd in ["stop", "stopp"]:
- return {'action':'stop', 'groups':groups}
+ return {'action': 'stop', 'groups': groups}
if len(send_groups) == 1:
group = send_groups[0]
if not group:
# can't figure out group, give up
- return {'action':'invalid'}
+ return {'action': 'invalid'}
if admin_cmd in ["stop", "stopp"]:
- return {'action':'stop', 'groups':groups}
-
+ return {'action': 'stop', 'groups': groups}
number = None
action = None
@@ -434,28 +437,28 @@ def _parse_action(self, src, phone, orig_msg):
action = 'add'
number = normalize_number(rest)
if action and number:
- return {'action':action, 'number':number, 'group':group}
+ return {'action': action, 'number': number, 'group': group}
else:
- return {'action':'invalid'}
+ return {'action': 'invalid'}
if lmsg.startswith(config.send_prefix):
send_msg = None
send_cmd = orig_msg[len(config.send_prefix):]
lfirst_word = send_cmd.split(" ")[0].lower()
for g in groups:
if lfirst_word == g['keyword'].lower():
- send_msg = "%s%s %s"%(config.send_prefix,g['keyword'],
+ send_msg = "%s%s %s" % (config.send_prefix, g['keyword'],
send_cmd[len(lfirst_word):].strip())
group = g
break
if send_msg and group:
- return {'action':'sendout', 'group':group, 'msg':send_msg}
+ return {'action': 'sendout', 'group': group, 'msg': send_msg}
- return {'action':'invalid'}
+ return {'action': 'invalid'}
def _handle_message(self, ids, src, phone, orig_msg):
- self._log("got message '%s' from %s to %s"%(orig_msg,src,phone))
- action = self._parse_action(src,phone,orig_msg)
+ self._log("got message '%s' from %s to %s" % (orig_msg, src, phone))
+ action = self._parse_action(src, phone, orig_msg)
status = 'invalid'
if action['action'] == 'stop':
@@ -466,32 +469,32 @@ def _handle_message(self, ids, src, phone, orig_msg):
group = action['group']
msg = action['msg']
if not src in [m['number'] for m in self.data.get_group_senders(group['id'])]:
- self._log("Warning: Unauthorized sendout command '%s' from %s to %s"%
- (orig_msg,src,phone))
+ self._log("Warning: Unauthorized sendout command '%s' from %s to %s" %
+ (orig_msg, src, phone))
status = 'unauthorized'
else:
- self._log("doing sendout to group %s"%group['name'])
+ self._log("doing sendout to group %s" % group['name'])
members = self.data.get_group_members(group['id'])
for member in members:
- self.sender.send(member['number'],msg)
+ self.sender.send(member['number'], msg)
self.data.increment_sent_stats(group['id'])
status = 'send'
- elif action['action'] in ['add','add_sender', 'add_admin']:
+ elif action['action'] in ['add', 'add_sender', 'add_admin']:
group = action['group']
if not src in [m['number'] for m in self.data.get_group_admins(group['id'])]:
- self._log("Warning: Unauthorized admin command '%s' from %s to %s"%(orig_msg,src,phone))
+ self._log("Warning: Unauthorized admin command '%s' from %s to %s" % (orig_msg, src, phone))
status = 'unauthorized'
else:
status = 'admin'
- self._log("doing command '%s' to group %s"%(action['action'],group['name']))
+ self._log("doing command '%s' to group %s" % (action['action'], group['name']))
mid = self.data.add_number(action['number'], None, group['id'])
- is_sender,is_admin = False,False
+ is_sender, is_admin = False, False
if action['action'] == 'add_sender':
self.data.set_member_info(mid, sender=True)
is_sender = True
elif action['action'] == 'add_admin':
self.data.set_member_info(mid, sender=True, admin=True)
- is_sender,is_admin = True,True
+ is_sender, is_admin = True, True
user_groups = self.data.get_groups(number=action['number'], phone=phone)
user_send_groups = self.data.get_send_groups(action['number'], phone=phone)
@@ -508,34 +511,36 @@ def _handle_message(self, ids, src, phone, orig_msg):
self.sender.send(src, msg)
for i in ids:
- self.data.set_processed(i,status)
+ self.data.set_processed(i, status)
def run(self):
self._log("starting doer")
messages = self.data.get_unprocessed()
for m in messages:
- self._handle_message(m['ids'],m['src'],m['phone'],m['text'])
+ self._handle_message(m['ids'], m['src'], m['phone'], m['text'])
self.cleanup()
+
class Sender:
def __init__(self):
- self.smsd = gammu.smsd.SMSD(config.smsdrc)
+ from gammu import smsd
+ self.smsd = smsd.SMSD(config.smsdrc)
def _log(self, text):
with open(config.log, "a") as log:
t = strftime("%Y-%m-%d %H:%M:%S", localtime())
- log.write("[%s] [doer] %s\n"%(t,text.encode('utf-8')));
+ log.write("[%s] [doer] %s\n" % (t, text.encode('utf-8')))
def send(self, dest, msg):
# this length calculation will fail will not work for some special
# gsm7 chars like [
- if len(msg) <= 160:
+ if len(msg) <= 160:
message = {'Text': msg, 'SMSC': {'Location': 1}, 'Number': dest}
- self._log("sending single part message "+str(message))
+ self._log("sending single part message " + str(message))
self.smsd.InjectSMS([message])
else:
# multipart
- self._log("sending multipart message");
+ self._log("sending multipart message")
smsinfo = {
'Class': 1,
'Unicode': False,
@@ -544,45 +549,47 @@ def send(self, dest, msg):
'Buffer': msg
}]}
# Encode messages
- encoded = gammu.EncodeSMS(smsinfo)
+ from gammu import EncodeSMS
+ encoded = EncodeSMS(smsinfo)
# Send messages
for message in encoded:
# Fill in numbers
message['SMSC'] = {'Location': 1}
message['Number'] = dest
# Actually send the message
- self._log("sending part of message: "+str(message));
+ self._log("sending part of message: " + str(message))
self.smsd.InjectSMS([message])
+
class Helper:
def get_welcomes(self, group_name, group_kw, is_sender, is_admin, groups, send_groups):
- msg = u"Välkommen till smslistan %s.\n"%group_name
+ msg = u"Välkommen till smslistan %s.\n" % group_name
if len(groups) == 1:
- msg += u"För att lämna listan skriv ett sms med texten \"stop\"."
+ msg += u"För att lämna listan skriv ett sms med texten \"stop\"."
else:
- msg += u"För att lämna listan skriv ett sms med texten \"%s%s stop\"."%(
+ msg += u"För att lämna listan skriv ett sms med texten \"%s%s stop\"." % (
config.admin_prefix, group_kw)
if is_sender:
- msg += u"\nFör att skicka ett sms, börja smset med %s%s."%(config.send_prefix, group_kw)
+ msg += u"\nFör att skicka ett sms, börja smset med %s%s." % (config.send_prefix, group_kw)
if is_admin:
- msg += u"\nFör att lägga till någon till listan, skicka \"%s%s add [nummer]\""%(config.admin_prefix,group_kw)
+ msg += u"\nFör att lägga till någon till listan, skicka \"%s%s add [nummer]\"" % (config.admin_prefix, group_kw)
return [msg]
def get_help(self, groups, send_groups, admin_groups):
msgs = []
send_names = [x['name'] for x in send_groups]
admin_names = [x['name'] for x in admin_groups]
for g in groups:
- msg = u"Det här är den automatiska smslistan %s.\n"%g['name']
+ msg = u"Det här är den automatiska smslistan %s.\n" % g['name']
if len(groups) == 1:
- msg += u"För att lämna listan skriv ett sms med texten \"stop\"."
+ msg += u"För att lämna listan skriv ett sms med texten \"stop\"."
else:
- msg += u"För att lämna listan skriv ett sms med texten \"%s%s stop\"."%(
+ msg += u"För att lämna listan skriv ett sms med texten \"%s%s stop\"." % (
config.admin_prefix, g['keyword'])
if g['name'] in send_names:
- msg += u"\nFör att skicka ett sms, börja smset med %s%s."%(config.send_prefix, g['keyword'])
+ msg += u"\nFör att skicka ett sms, börja smset med %s%s." % (config.send_prefix, g['keyword'])
if g['name'] in admin_names:
- msg += u"\nFör att lägga till någon till listan, skicka \"%s%s add [nummer]\""%(config.admin_prefix,g['keyword'])
+ msg += u"\nFör att lägga till någon till listan, skicka \"%s%s add [nummer]\"" % (config.admin_prefix, g['keyword'])
msgs.append(msg)
return msgs
View
25 core_test.py
@@ -1,6 +1,7 @@
import core
from config import config
+
class TestData:
def setUp(self):
config.db = config.test_db
@@ -30,7 +31,7 @@ def test_get_groups(self):
gs = self.data.get_groups(phone=phone)
assert 2 == len(gs)
- gs = self.data.get_groups(phone=phone,number=number1)
+ gs = self.data.get_groups(phone=phone, number=number1)
assert 1 == len(gs)
assert 'group1' == gs[0]['name']
@@ -113,11 +114,12 @@ def test_get_unprocessed(self):
assert "phone1" == u[0]['phone']
assert "hello" == u[0]['text']
+
class TestDoer:
def setUp(self):
config.db = config.test_db
config.smsdrc = config.test_smsdrc
- self.sender = FakeSender() #core.Sender()
+ self.sender = FakeSender() # core.Sender()
self.doer = core.Doer(self.sender)
self.data = core.Data()
self.data.setup_db()
@@ -160,7 +162,7 @@ def test_run_admin_command_add_unauthorized(self):
assert not "+4673123" in [x['number'] for x in self.data.get_group_members(gid)]
assert not "+4673123" in [x['number'] for x in self.data.get_group_senders(gid)]
assert not "+4673123" in [x['number'] for x in self.data.get_group_admins(gid)]
- assert len(self.sender.sendouts) == 1 # help message
+ assert len(self.sender.sendouts) == 1 # help message
assert self.sender.sendouts[0][0] == number
def test_run_admin_command_add(self):
@@ -174,7 +176,7 @@ def test_run_admin_command_add(self):
assert "+4673123" in [x['number'] for x in self.data.get_group_members(gid)]
assert not "+4673123" in [x['number'] for x in self.data.get_group_senders(gid)]
assert not "+4673123" in [x['number'] for x in self.data.get_group_admins(gid)]
- assert len(self.sender.sendouts) == 1 # welcome message
+ assert len(self.sender.sendouts) == 1 # welcome message
assert self.sender.sendouts[0][0] == "+4673123"
def test_run_admin_command_add_sender(self):
@@ -188,7 +190,7 @@ def test_run_admin_command_add_sender(self):
assert "+4673123" in [x['number'] for x in self.data.get_group_members(gid)]
assert "+4673123" in [x['number'] for x in self.data.get_group_senders(gid)]
assert not "+4673123" in [x['number'] for x in self.data.get_group_admins(gid)]
- assert len(self.sender.sendouts) == 1 # welcome message
+ assert len(self.sender.sendouts) == 1 # welcome message
assert self.sender.sendouts[0][0] == "+4673123"
def test_run_admin_command_add_admin(self):
@@ -202,7 +204,7 @@ def test_run_admin_command_add_admin(self):
assert "+4673123" in [x['number'] for x in self.data.get_group_members(gid)]
assert "+4673123" in [x['number'] for x in self.data.get_group_senders(gid)]
assert "+4673123" in [x['number'] for x in self.data.get_group_admins(gid)]
- assert len(self.sender.sendouts) == 1 # welcome message
+ assert len(self.sender.sendouts) == 1 # welcome message
assert self.sender.sendouts[0][0] == "+4673123"
def test_run_admin_command_add_keyword(self):
@@ -216,7 +218,7 @@ def test_run_admin_command_add_keyword(self):
assert "+4673123" in [x['number'] for x in self.data.get_group_members(gid)]
assert not "+4673123" in [x['number'] for x in self.data.get_group_senders(gid)]
assert not "+4673123" in [x['number'] for x in self.data.get_group_admins(gid)]
- assert len(self.sender.sendouts) == 1 # welcome message
+ assert len(self.sender.sendouts) == 1 # welcome message
assert self.sender.sendouts[0][0] == "+4673123"
def test_run_admin_command_add_sender_keyword(self):
@@ -230,7 +232,7 @@ def test_run_admin_command_add_sender_keyword(self):
assert "+4673123" in [x['number'] for x in self.data.get_group_members(gid)]
assert "+4673123" in [x['number'] for x in self.data.get_group_senders(gid)]
assert not "+4673123" in [x['number'] for x in self.data.get_group_admins(gid)]
- assert len(self.sender.sendouts) == 1 # welcome message
+ assert len(self.sender.sendouts) == 1 # welcome message
assert self.sender.sendouts[0][0] == "+4673123"
def test_run_admin_command_add_admin_keyword(self):
@@ -244,7 +246,7 @@ def test_run_admin_command_add_admin_keyword(self):
assert "+4673123" in [x['number'] for x in self.data.get_group_members(gid)]
assert "+4673123" in [x['number'] for x in self.data.get_group_senders(gid)]
assert "+4673123" in [x['number'] for x in self.data.get_group_admins(gid)]
- assert len(self.sender.sendouts) == 1 # welcome message
+ assert len(self.sender.sendouts) == 1 # welcome message
assert self.sender.sendouts[0][0] == "+4673123"
def test_run_sendout_unauthorized(self):
@@ -292,7 +294,7 @@ def test_run_sendout(self):
doer = core.Doer(s)
self.data.fake_incoming(number, phone, "test")
doer.run()
- assert 1 == len(s.sendouts) # test message
+ assert 1 == len(s.sendouts) # test message
assert s.sendouts[0][0] == number
def test_run_sendout_prefix(self):
@@ -309,9 +311,10 @@ def test_run_sendout_prefix(self):
assert 1 == len(s.sendouts)
assert (number, "#keyword test") == s.sendouts[0]
+
class FakeSender:
def __init__(self):
self.sendouts = []
def send(self, dest, msg):
- self.sendouts.append((dest,msg))
+ self.sendouts.append((dest, msg))
View
47 smskrupp
@@ -4,16 +4,17 @@ import sys
import core
from config import config
+
def usage():
- print("%s add-group <name> <keyword>"%sys.argv[0])
- print("%s list-groups"%sys.argv[0])
- print("%s list-members <group>"%sys.argv[0])
- print("%s add-member <number> <alias> <group>"%sys.argv[0])
- print("%s rm-member <number> <group|ALL>"%sys.argv[0])
- print("%s set-sender <number> <group>"%sys.argv[0])
- print("%s set-admin <number> <group>"%sys.argv[0])
- print("%s fake-incoming <src> <phone> <msg>"%sys.argv[0])
- print("%s add-webadmin <login> <password>"%sys.argv[0])
+ print("%s add-group <name> <keyword>" % sys.argv[0])
+ print("%s list-groups" % sys.argv[0])
+ print("%s list-members <group>" % sys.argv[0])
+ print("%s add-member <number> <alias> <group>" % sys.argv[0])
+ print("%s rm-member <number> <group|ALL>" % sys.argv[0])
+ print("%s set-sender <number> <group>" % sys.argv[0])
+ print("%s set-admin <number> <group>" % sys.argv[0])
+ print("%s fake-incoming <src> <phone> <msg>" % sys.argv[0])
+ print("%s add-webadmin <login> <password>" % sys.argv[0])
sys.exit(1)
if len(sys.argv) < 2:
@@ -36,17 +37,20 @@ elif sys.argv[1] == 'list-members':
print "no such group!"
sys.exit(1)
for member in data.get_group_members(gid):
- if member['sender']: s = 's'
+ if member['sender']:
+ s = 's'
else:
s = ' '
- if member['admin']: s = 'a'+s
- else: s = ' '+s
- s += ' %s [%s]'%(member['alias'],member['number'])
+ if member['admin']:
+ s = 'a' + s
+ else:
+ s = ' ' + s
+ s += ' %s [%s]' % (member['alias'], member['number'])
print(s)
elif sys.argv[1] == 'add-member':
if len(sys.argv) != 5:
usage()
- number,alias,group = sys.argv[2:]
+ number, alias, group = sys.argv[2:]
number = core.normalize_number(number)
if not number:
print "number error!"
@@ -61,7 +65,7 @@ elif sys.argv[1] == 'add-member':
elif sys.argv[1] == 'rm-member':
if len(sys.argv) != 4:
usage()
- number,group = sys.argv[2:]
+ number, group = sys.argv[2:]
number = core.normalize_number(number)
if not number:
print "number error!"
@@ -80,13 +84,13 @@ elif sys.argv[1] == 'set-sender':
if len(sys.argv) != 4:
usage()
- number,group = sys.argv[2:]
+ number, group = sys.argv[2:]
number = core.normalize_number(number)
group_id = data.get_group_id(group)
if not group_id:
print "group error!"
sys.exit(1)
- mid = data.get_member_id(number, group_id);
+ mid = data.get_member_id(number, group_id)
if not mid:
print "no such number!"
sys.exit(1)
@@ -95,31 +99,30 @@ elif sys.argv[1] == 'set-admin':
if len(sys.argv) != 4:
usage()
- number,group = sys.argv[2:]
+ number, group = sys.argv[2:]
number = core.normalize_number(number)
group_id = data.get_group_id(group)
if not group_id:
print "group error!"
sys.exit(1)
- mid = data.get_member_id(number, group_id);
+ mid = data.get_member_id(number, group_id)
if not mid:
print "no such number!"
sys.exit(1)
data.set_member_info(mid, sender=True, admin=True)
elif sys.argv[1] == 'fake-incoming':
if len(sys.argv) != 5:
usage()
- src,phone,msg = sys.argv[2:]
+ src, phone, msg = sys.argv[2:]
src = core.normalize_number(src)
if not src:
print "number error!"
sys.exit(1)
- data.fake_incoming(src,phone,msg)
+ data.fake_incoming(src, phone, msg)
elif sys.argv[1] == 'add-webadmin':
if len(sys.argv) != 4:
usage()
login, password = sys.argv[2:]
data.add_webuser(login, password, 2)
else:
usage()
-
View
35 web.py
@@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
import sqlite3
-from flask import Flask,render_template,request,session,flash,redirect, \
- url_for,abort, g
+from flask import Flask, render_template, request, session, flash, redirect, \
+ url_for, abort, g
from config import config
import core
@@ -15,15 +15,18 @@
app.debug = config.debug
app.secret_key = config.flask_key
+
def connect_db():
"""Returns a new connection to the database."""
return sqlite3.connect(config.db)
+
@app.before_request
def before_request():
"""Make sure we are connected to the database each request."""
g.db = connect_db()
+
@app.teardown_request
def teardown_request(exception):
"""Closes the database again at the end of the request."""
@@ -61,7 +64,7 @@ def groups(name=None):
gid = data.add_group(request.form['name'], request.form['keyword'],
config.default_phone)
data.set_webuser_group(session.get('userid'), gid)
- return redirect(url_for('groups')+request.form['name'])
+ return redirect(url_for('groups') + request.form['name'])
members = None
if not session.get('admin'):
@@ -80,7 +83,8 @@ def groups(name=None):
return render_template('group.html', name=name, members=members, groups=groups, error=error)
-@app.route('/removemember/<mid>')
+
+@app.route('/removemember/<mid>')
def remove_member(mid=None):
data = core.Data()
info = data.get_member_info(mid)
@@ -94,7 +98,8 @@ def remove_member(mid=None):
data.remove_number(mid)
return redirect(url_for('groups', name=info['groupName']))
-@app.route('/removegroup/<name>')
+
+@app.route('/removegroup/<name>')
def remove_group(name):
data = core.Data()
gid = data.get_group_id(name)
@@ -109,7 +114,8 @@ def remove_group(name):
data.remove_group(gid)
return redirect(url_for('groups'))
-@app.route("/settings", methods=['POST','GET'])
+
+@app.route("/settings", methods=['POST', 'GET'])
def settings():
if not session.get('admin'):
abort(401)
@@ -125,19 +131,21 @@ def settings():
data.set_webuser_pw(request.form['userid'], request.form['pw'])
groups = data.get_groups()
- return render_template('settings.html', webusers=data.get_webusers(),groups=groups)
+ return render_template('settings.html', webusers=data.get_webusers(), groups=groups)
-@app.route('/removewebusergroup/<uid>/<gid>')
-def remove_webuser_group(uid,gid):
+
+@app.route('/removewebusergroup/<uid>/<gid>')
+def remove_webuser_group(uid, gid):
if not session.get('admin'):
abort(401)
data = core.Data()
- data.remove_webuser_group(uid,gid)
+ data.remove_webuser_group(uid, gid)
return redirect(url_for('settings'))
-@app.route('/removewebuser/<uid>')
+
+@app.route('/removewebuser/<uid>')
def remove_webuser(uid):
if not session.get('admin'):
abort(401)
@@ -146,13 +154,14 @@ def remove_webuser(uid):
data.remove_webuser(uid)
return redirect(url_for('settings'))
+
@app.route("/")
@app.route('/login', methods=['POST', 'GET'])
def login():
error = None
if request.method == 'POST':
data = core.Data()
- userid,privilege = data.check_webuser_login(request.form['username'],
+ userid, privilege = data.check_webuser_login(request.form['username'],
request.form['password'])
if privilege:
session['username'] = request.form['username']
@@ -165,6 +174,7 @@ def login():
error = 'Invalid username/password'
return render_template('login.html', error=error)
+
@app.route('/logout')
def logout():
session.pop('username', None)
@@ -176,4 +186,3 @@ def logout():
if __name__ == '__main__':
app.run()
-

0 comments on commit 5e54a05

Please sign in to comment.