self._on_conversations_updated
)
)
- self._conn.session.conversations.updateSignalHandler.register_sink(
+ self._conn.session.voicemails.updateSignalHandler.register_sink(
+ self._callback
+ )
+ self._conn.session.texts.updateSignalHandler.register_sink(
self._callback
)
# The only reason there should be anything in the conversation is if
# its new, so report it all
try:
- mergedConversations = self._conn.session.conversations.get_conversation(self._contactKey)
+ mergedConversations = self._conn.session.voicemails.get_conversation(self._contactKey)
+ except KeyError:
+ _moduleLogger.info("Nothing in the conversation yet for %r" % (self._contactKey, ))
+ else:
+ self._report_conversation(mergedConversations)
+ try:
+ mergedConversations = self._conn.session.texts.get_conversation(self._contactKey)
except KeyError:
_moduleLogger.info("Nothing in the conversation yet for %r" % (self._contactKey, ))
else:
raise telepathy.errors.NotImplemented("Unhandled message type: %r" % messageType)
self._conn.session.backend.send_sms(self._otherHandle.phoneNumber, text)
- self._conn.session.conversationsStateMachine.reset_timers()
+ self._conn.session.textsStateMachine.reset_timers()
self.Sent(int(time.time()), messageType, text)
self.close()
def close(self):
- self._conn.session.conversations.updateSignalHandler.unregister_sink(
+ self._conn.session.voicemails.updateSignalHandler.unregister_sink(
+ self._callback
+ )
+ self._conn.session.texts.updateSignalHandler.unregister_sink(
self._callback
)
self._callback = None
if self._contactKey not in conversationIds:
return
_moduleLogger.info("Incoming messages from %r for existing conversation" % (self._contactKey, ))
- mergedConversations = self._conn.session.conversations.get_conversation(self._contactKey)
+ mergedConversations = conv.get_conversation(self._contactKey)
self._report_conversation(mergedConversations)
def _report_conversation(self, mergedConversations):
"""
-@todo Add params for disable/enable state machines
-@todo Separate voicemail/sms into separate conversation instances
-@todo Setup addressbook, voicemail, sms state machines
+@todo Add params for different state machines update times
@todo Add option to use screen name as callback
@todo Get a callback for missed calls to force an update of the voicemail state machine
@todo Get a callback on an incoming call and if its from GV, auto-pickup
-@todo Use state-strategies to keep mega-state-machine generic
@todo Observe when connected/disconnected to disconnect CM
"""
self._on_conversations_updated
)
)
- self.session.conversations.updateSignalHandler.register_sink(
+ self.session.voicemails.updateSignalHandler.register_sink(
+ self._callback
+ )
+ self.session.texts.updateSignalHandler.register_sink(
self._callback
)
self.session.login(*self._credentials)
"""
_moduleLogger.info("Disconnecting")
try:
- self.session.conversations.updateSignalHandler.unregister_sink(
+ self.session.voicemails.updateSignalHandler.unregister_sink(
+ self._callback
+ )
+ self.session.texts.updateSignalHandler.unregister_sink(
self._callback
)
self._callback = None
@gobject_utils.async
@gtk_toolbox.log_exception(_moduleLogger)
def _on_conversations_updated(self, conv, conversationIds):
- # @todo get conversations update running
- # @todo test conversatiuons
_moduleLogger.info("Incoming messages from: %r" % (conversationIds, ))
for contactId, phoneNumber in conversationIds:
h = handle.create_handle(self, 'contact', contactId, phoneNumber)
if contactId != "0":
yield contactId, contactDetails
- def get_conversations(self):
+ def get_voicemails(self):
voicemailPage = self._get_page(self._XML_VOICEMAIL_URL)
voicemailHtml = self._grab_html(voicemailPage)
voicemailJson = self._grab_json(voicemailPage)
parsedVoicemail = self._parse_voicemail(voicemailHtml)
voicemails = self._merge_conversation_sources(parsedVoicemail, voicemailJson)
+ return voicemails
+ def get_texts(self):
smsPage = self._get_page(self._XML_SMS_URL)
smsHtml = self._grab_html(smsPage)
smsJson = self._grab_json(smsPage)
parsedSms = self._parse_sms(smsHtml)
smss = self._merge_conversation_sources(parsedSms, smsJson)
-
- allConversations = itertools.chain(voicemails, smss)
- return allConversations
+ return smss
def mark_message(self, messageId, asRead):
postData = {
class Conversations(object):
- def __init__(self, backend):
- self._backend = backend
+ def __init__(self, getter):
+ self._get_raw_conversations = getter
self._conversations = {}
self.updateSignalHandler = coroutines.CoTee()
oldConversationIds = set(self._conversations.iterkeys())
updateConversationIds = set()
- conversations = list(self._backend.get_conversations())
+ conversations = list(self._get_raw_conversations())
conversations.sort()
for conversation in conversations:
key = conversation.contactId, util_misc.strip_number(conversation.number)
self._backend = backend.GVoiceBackend(cookiePath)
self._addressbook = addressbook.Addressbook(self._backend)
- self._addressbookStateMachine = state_machine.UpdateStateMachine([self.addressbook])
+ self._addressbookStateMachine = state_machine.UpdateStateMachine([self.addressbook], "Addressbook")
self._addressbookStateMachine.set_state_strategy(
state_machine.StateMachine.STATE_DND,
state_machine.NopStateStrategy()
state_machine.ConstantStateStrategy(state_machine.to_milliseconds(hours=1))
)
- self._conversations = conversations.Conversations(self._backend)
- self._conversationsStateMachine = state_machine.UpdateStateMachine([self.conversations])
- self._conversationsStateMachine.set_state_strategy(
+ self._voicemails = conversations.Conversations(self._backend.get_voicemails)
+ self._voicemailsStateMachine = state_machine.UpdateStateMachine([self.voicemails], "Voicemail")
+ self._voicemailsStateMachine.set_state_strategy(
state_machine.StateMachine.STATE_DND,
state_machine.NopStateStrategy()
)
- self._conversationsStateMachine.set_state_strategy(
+ self._voicemailsStateMachine.set_state_strategy(
state_machine.StateMachine.STATE_IDLE,
state_machine.ConstantStateStrategy(state_machine.to_milliseconds(minutes=30))
)
- self._conversationsStateMachine.set_state_strategy(
+ self._voicemailsStateMachine.set_state_strategy(
+ state_machine.StateMachine.STATE_ACTIVE,
+ state_machine.ConstantStateStrategy(state_machine.to_milliseconds(minutes=5))
+ )
+ self._voicemails.updateSignalHandler.register_sink(
+ self._voicemailsStateMachine.request_reset_timers
+ )
+
+ self._texts = conversations.Conversations(self._backend.get_texts)
+ self._textsStateMachine = state_machine.UpdateStateMachine([self.texts], "Texting")
+ self._textsStateMachine.set_state_strategy(
+ state_machine.StateMachine.STATE_DND,
+ state_machine.NopStateStrategy()
+ )
+ self._textsStateMachine.set_state_strategy(
+ state_machine.StateMachine.STATE_IDLE,
+ state_machine.ConstantStateStrategy(state_machine.to_milliseconds(minutes=30))
+ )
+ self._textsStateMachine.set_state_strategy(
state_machine.StateMachine.STATE_ACTIVE,
state_machine.GeometricStateStrategy(
state_machine.to_milliseconds(seconds=10),
state_machine.to_milliseconds(minutes=10),
)
)
+ self._texts.updateSignalHandler.register_sink(
+ self._textsStateMachine.request_reset_timers
+ )
self._masterStateMachine = state_machine.MasterStateMachine()
self._masterStateMachine.append_machine(self._addressbookStateMachine)
- self._masterStateMachine.append_machine(self._conversationsStateMachine)
-
- self._conversations.updateSignalHandler.register_sink(
- self._conversationsStateMachine.request_reset_timers
- )
+ self._masterStateMachine.append_machine(self._voicemailsStateMachine)
+ self._masterStateMachine.append_machine(self._textsStateMachine)
def close(self):
- self._conversations.updateSignalHandler.unregister_sink(
- self._conversationsStateMachine.request_reset_timers
+ self._voicemails.updateSignalHandler.unregister_sink(
+ self._voicemailsStateMachine.request_reset_timers
+ )
+ self._texts.updateSignalHandler.unregister_sink(
+ self._textsStateMachine.request_reset_timers
)
self._masterStateMachine.close()
@property
def addressbook(self):
- """
- Delay initialized addressbook
- """
return self._addressbook
@property
- def conversations(self):
- """
- Delay initialized addressbook
- """
- return self._conversations
+ def texts(self):
+ return self._texts
+
+ @property
+ def voicemails(self):
+ return self._voicemails
@property
def stateMachine(self):
return self._addressbookStateMachine
@property
- def conversationsStateMachine(self):
- return self._conversationsStateMachine
+ def voicemailsStateMachine(self):
+ return self._voicemailsStateMachine
+
+ @property
+ def textsStateMachine(self):
+ return self._textsStateMachine
_IS_DAEMON = True
- def __init__(self, updateItems):
+ def __init__(self, updateItems, name=""):
+ self._name = name
self._updateItems = updateItems
self._state = self.STATE_ACTIVE
def _strategy(self):
return self._strategies[self._state]
- @property
- def _name(self):
- return "/".join(type(s).__name__ for s in self._updateItems)
-
@gobject_utils.async
@gtk_toolbox.log_exception(_moduleLogger)
def _request_reset_timers(self, *args):