2013-08-01 23:45:51 +00:00
__author__ = " Steffen Vogel "
__copyright__ = " Copyright 2013, Steffen Vogel "
__license__ = " GPLv3 "
__maintainer__ = " Steffen Vogel "
__email__ = " post@steffenvogel.de "
__status__ = " Prototype "
"""
This file is part of transWhat
transWhat 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 .
transwhat 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 transWhat . If not , see < http : / / www . gnu . org / licenses / > .
"""
2013-06-28 17:46:25 +00:00
from Spectrum2 import protocol_pb2
import logging
2015-11-09 22:09:12 +00:00
import threading
2013-06-28 17:46:25 +00:00
class Number ( ) :
def __init__ ( self , number , state , db ) :
self . number = number
self . db = db
self . state = state
cur = self . db . cursor ( )
cur . execute ( " SELECT id FROM numbers WHERE number = %s AND state = %s " , ( self . number , self . state ) )
if ( cur . rowcount ) :
self . id = cur . fetchone ( ) [ 0 ]
else :
cur . execute ( " REPLACE numbers (number, state) VALUES ( %s , %s ) " , ( self . number , self . state ) )
self . db . commit ( )
self . id = cur . lastrowid
def __str__ ( self ) :
return " %s (id= %s ) " % ( self . number , self . id )
class Buddy ( ) :
2015-09-05 22:14:12 +00:00
def __init__ ( self , owner , number , nick , groups , image_hash , id , db ) :
2013-06-28 17:46:25 +00:00
self . id = id
self . db = db
self . nick = nick
self . owner = owner
self . number = number
self . groups = groups
2015-11-10 18:39:25 +00:00
self . image_hash = image_hash if image_hash is not None else " "
2015-11-09 22:09:12 +00:00
self . statusMsg = " "
2015-11-10 16:04:20 +00:00
self . lastseen = 0
self . presence = 0
2015-11-09 22:09:12 +00:00
2013-06-28 17:46:25 +00:00
2015-09-05 22:14:12 +00:00
def update ( self , nick , groups , image_hash ) :
2013-06-28 17:46:25 +00:00
self . nick = nick
self . groups = groups
2015-09-21 18:30:11 +00:00
if image_hash is not None :
self . image_hash = image_hash
2013-06-28 17:46:25 +00:00
groups = u " , " . join ( groups ) . encode ( " latin-1 " )
cur = self . db . cursor ( )
2015-11-09 22:09:12 +00:00
cur . execute ( " UPDATE buddies SET nick = %s , groups = %s , image_hash = %s WHERE owner_id = %s AND buddy_id = %s " , ( self . nick , groups , self . image_hash , self . owner . id , self . number . id ) )
2013-06-28 17:46:25 +00:00
self . db . commit ( )
def delete ( self ) :
cur = self . db . cursor ( )
cur . execute ( " DELETE FROM buddies WHERE owner_id = %s AND buddy_id = %s " , ( self . owner . id , self . number . id ) )
self . db . commit ( )
self . id = None
@staticmethod
2015-09-05 22:14:12 +00:00
def create ( owner , number , nick , groups , image_hash , db ) :
2013-06-28 17:46:25 +00:00
groups = u " , " . join ( groups ) . encode ( " latin-1 " )
cur = db . cursor ( )
2015-09-05 22:14:12 +00:00
cur . execute ( " REPLACE buddies (owner_id, buddy_id, nick, groups, image_hash) VALUES ( %s , %s , %s , %s , %s ) " , ( owner . id , number . id , nick , groups , image_hash ) )
2013-06-28 17:46:25 +00:00
db . commit ( )
2015-09-05 22:14:12 +00:00
return Buddy ( owner , number , nick , groups , image_hash , cur . lastrowid , db )
2013-06-28 17:46:25 +00:00
def __str__ ( self ) :
return " %s (nick= %s , id= %s ) " % ( self . number , self . nick , self . id )
class BuddyList ( dict ) :
def __init__ ( self , owner , db ) :
self . db = db
self . owner = Number ( owner , 1 , db )
2015-11-09 22:09:12 +00:00
self . lock = threading . Lock ( )
2013-06-28 17:46:25 +00:00
def load ( self ) :
self . clear ( )
2015-11-09 22:09:12 +00:00
self . lock . acquire ( )
2013-06-28 17:46:25 +00:00
cur = self . db . cursor ( )
cur . execute ( """ SELECT
b . id AS id ,
n . number AS number ,
b . nick AS nick ,
b . groups AS groups ,
2015-09-05 22:14:12 +00:00
n . state AS state ,
b . image_hash AS image_hash
2013-06-28 17:46:25 +00:00
FROM buddies AS b
LEFT JOIN numbers AS n
ON b . buddy_id = n . id
WHERE
b . owner_id IN ( % s , 0 )
AND n . state > = 1
ORDER BY b . owner_id DESC """ , self.owner.id)
for i in range ( cur . rowcount ) :
2015-09-05 22:14:12 +00:00
id , number , nick , groups , state , image_hash = cur . fetchone ( )
self [ number ] = Buddy ( self . owner , Number ( number , state , self . db ) , nick . decode ( ' latin1 ' ) , groups . split ( " , " ) , image_hash , id , self . db )
2015-11-09 22:09:12 +00:00
self . lock . release ( )
2013-06-28 17:46:25 +00:00
2015-09-05 22:14:12 +00:00
def update ( self , number , nick , groups , image_hash ) :
2015-11-09 22:09:12 +00:00
self . lock . acquire ( )
2013-06-28 17:46:25 +00:00
if number in self :
buddy = self [ number ]
2015-09-05 22:14:12 +00:00
buddy . update ( nick , groups , image_hash )
2013-06-28 17:46:25 +00:00
else :
2015-09-05 22:14:12 +00:00
buddy = self . add ( number , nick , groups , 1 , image_hash )
2015-11-09 22:09:12 +00:00
self . lock . release ( )
2013-06-28 17:46:25 +00:00
return buddy
2015-09-05 22:14:12 +00:00
def add ( self , number , nick , groups = [ ] , state = 0 , image_hash = " " ) :
return Buddy . create ( self . owner , Number ( number , state , self . db ) , nick , groups , image_hash , self . db )
2013-06-28 17:46:25 +00:00
def remove ( self , number ) :
2015-09-03 18:04:29 +00:00
try :
buddy = self [ number ]
2015-11-09 22:09:12 +00:00
self . lock . acquire ( )
2015-09-03 18:04:29 +00:00
buddy . delete ( )
2015-11-09 22:09:12 +00:00
self . lock . release ( )
2015-09-03 18:04:29 +00:00
return buddy
except KeyError :
return None
2013-06-28 17:46:25 +00:00
def prune ( self ) :
2015-11-09 22:09:12 +00:00
self . lock . acquire ( )
2013-06-28 17:46:25 +00:00
cur = self . db . cursor ( )
cur . execute ( " DELETE FROM buddies WHERE owner_id = %s " , self . owner . id )
self . db . commit ( )
2015-11-09 22:09:12 +00:00
self . lock . release ( )
2013-06-28 17:46:25 +00:00
def sync ( self , user , password ) :
2015-11-09 22:09:12 +00:00
self . lock . acquire ( )
2013-06-28 17:46:25 +00:00
cur = self . db . cursor ( )
cur . execute ( """ SELECT
n . number AS number ,
n . state AS state
FROM buddies AS r
LEFT JOIN numbers AS n
ON r . buddy_id = n . id
WHERE
r . owner_id = % s """ , self.owner.id)
# prefix every number with leading 0 to force internation format
numbers = dict ( [ ( " + " + number , state ) for number , state in cur . fetchall ( ) ] )
if len ( numbers ) == 0 :
return 0
result = WAContactsSyncRequest ( user , password , numbers . keys ( ) ) . send ( )
using = 0
for number in result [ ' c ' ] :
cur = self . db . cursor ( )
cur . execute ( " UPDATE numbers SET state = %s WHERE number = %s " , ( number [ ' w ' ] , number [ ' n ' ] ) )
self . db . commit ( )
using + = number [ ' w ' ]
2015-11-09 22:09:12 +00:00
self . lock . release ( )
2013-06-28 17:46:25 +00:00
return using