From 37ad12a05c20e0941a54fe6bc9c7773fbb805d6c Mon Sep 17 00:00:00 2001 From: Ed Page Date: Sat, 30 Jan 2010 21:43:01 -0600 Subject: [PATCH 1/1] Starting to add access to the debug log --- src/channel/__init__.py | 1 + src/channel/debug_log.py | 125 +++++++++++++++++++++++++++++++++++++++++++ src/channel/debug_prompt.py | 13 ++++- src/channel_manager.py | 24 +++++++-- 4 files changed, 159 insertions(+), 4 deletions(-) create mode 100644 src/channel/debug_log.py diff --git a/src/channel/__init__.py b/src/channel/__init__.py index 7625b70..6e5efdf 100644 --- a/src/channel/__init__.py +++ b/src/channel/__init__.py @@ -4,3 +4,4 @@ import contact_list import text import call import debug_prompt +import debug_log diff --git a/src/channel/debug_log.py b/src/channel/debug_log.py new file mode 100644 index 0000000..2a1c188 --- /dev/null +++ b/src/channel/debug_log.py @@ -0,0 +1,125 @@ +from __future__ import with_statement + +import socket +import logging + +import telepathy + +import constants +import tp +import gtk_toolbox + + +_moduleLogger = logging.getLogger("channel.debug_log") + + +class DebugLogChannel(tp.ChannelTypeFileTransfer): + + def __init__(self, connection, manager, props, contactHandle): + self.__manager = manager + self.__props = props + self.__otherHandle = contactHandle + + tp.ChannelTypeFileTransfer.__init__(self, connection, manager, props) + + dbus_interface = telepathy.CHANNEL_TYPE_FILE_TRANSFER + self._implement_property_get( + dbus_interface, + { + 'State': self.get_state, + "ContentType": self.get_content_type, + "Filename": self.get_filename, + "Size": self.get_state, + "Description": self.get_description, + "AvailableSocketTypes": self.get_available_socket_types, + "TransferredBytes": self.get_transferred_bytes, + "InitialOffset": self.get_initial_offset, + }, + ) + + # grab a snapshot of the log so that we are always in a consistent + # state between calls + with open(constants._user_logpath_, "r") as f: + logLines = f.xreadlines() + self._log = "".join(logLines) + self._transferredBytes = 0 + + self._state = telepathy.constants.FILE_TRANSFER_STATE_PENDING + self.FileTransferStateChanged( + self._state, + telepathy.constants.FILE_TRANSFER_STATE_CHANGE_REASON_NONE, + ) + + def get_state(self): + return self._state + + def get_content_type(self): + return "application/octet-stream" + + def get_filename(self): + return "%s.log" % constants._telepathy_implementation_name_ + + def get_size(self): + return len(self._log) + + def get_description(self): + return "Debug log for The One Ring" + + def get_available_socket_types(self): + return { + telepathy.constants.SOCKET_ADDRESS_TYPE_UNIX: [ + telepathy.constants.SOCKET_ACCESS_CONTROL_LOCALHOST, + telepathy.constants.SOCKET_ACCESS_CONTROL_CREDENTIALS, + ], + } + + def get_transferred_bytes(self): + return self._transferredBytes + + def get_initial_offset(self): + return 0 + + @gtk_toolbox.log_exception(_moduleLogger) + def AcceptFile(self, addressType, accessControl, accessControlParam, offset): + _moduleLogger.info("%r %r %r %r" % (addressType, accessControl, accessControlParam, offset)) + self.InitialOffsetDefined(0) + self._state = telepathy.constants.FILE_TRANSFER_STATE_ACCEPTED + self.FileTransferStateChanged( + self._state, + telepathy.constants.FILE_TRANSFER_STATE_CHANGE_REASON_REQUESTED, + ) + + self._state = telepathy.constants.FILE_TRANSFER_STATE_OPEN + self.FileTransferStateChanged( + self._state, + telepathy.constants.FILE_TRANSFER_STATE_CHANGE_REASON_NONE, + ) + + sockittome = socket.socket(socket.AF_UNIT, socket.SOCK_STREAM) + sockittome.connect(accessControlParam) + try: + sockittome.send(self._log) + finally: + sockittome.close() + + self._transferredBytes = len(self._log) + self.TransferredBytesChanged(self._transferredBytes) + + self._state = telepathy.constants.FILE_TRANSFER_STATE_COMPLETED + self.FileTransferStateChanged( + self._state, + telepathy.constants.FILE_TRANSFER_STATE_CHANGE_REASON_NONE, + ) + + @gtk_toolbox.log_exception(_moduleLogger) + def ProvideFile(self, addressType, accessControl, accessControlParam): + raise telepathy.errors.NotImplemented("Cannot send outbound files") + + @gtk_toolbox.log_exception(_moduleLogger) + def Close(self): + self.close() + + def close(self): + _moduleLogger.debug("Closing log") + tp.ChannelTypeFileTransfer.Close(self) + self.remove_from_connection() diff --git a/src/channel/debug_prompt.py b/src/channel/debug_prompt.py index 72091d0..86a3e37 100644 --- a/src/channel/debug_prompt.py +++ b/src/channel/debug_prompt.py @@ -12,7 +12,7 @@ import gtk_toolbox import gvoice -_moduleLogger = logging.getLogger("channel.text") +_moduleLogger = logging.getLogger("channel.debug_prompt") class DebugPromptChannel(tp.ChannelTypeText, cmd.Cmd): @@ -237,3 +237,14 @@ class DebugPromptChannel(tp.ChannelTypeText, cmd.Cmd): def help_get_polling(self): self._report_new_message("Prints the frequency each of the state machines updates") + + def do_grab_log(self, args): + if args: + self._report_new_message("No arguments supported") + return + publishProps = self._conn._generate_props(telepathy.CHANNEL_TYPE_FILE_TRANSFER, self.__otherHandle, False) + self._conn._channel_manager.channel_for_props(publishProps, signal=True) + + def help_grab_log(self): + self._report_new_message("Download the debug log for including with bug report") + self._report_new_message("Warning: this may contain sensitive information") diff --git a/src/channel_manager.py b/src/channel_manager.py index bce767b..04faca1 100644 --- a/src/channel_manager.py +++ b/src/channel_manager.py @@ -17,6 +17,16 @@ class ChannelManager(tp.ChannelManager): tp.ChannelManager.__init__(self, connection) fixed = { + telepathy.CHANNEL_INTERFACE + '.ChannelType': telepathy.CHANNEL_TYPE_CONTACT_LIST + } + self._implement_channel_class( + telepathy.CHANNEL_TYPE_CONTACT_LIST, + self._get_list_channel, + fixed, + [] + ) + + fixed = { telepathy.CHANNEL_INTERFACE + '.ChannelType': telepathy.CHANNEL_TYPE_TEXT, telepathy.CHANNEL_INTERFACE + '.TargetHandleType': dbus.UInt32(telepathy.HANDLE_TYPE_CONTACT) } @@ -28,11 +38,12 @@ class ChannelManager(tp.ChannelManager): ) fixed = { - telepathy.CHANNEL_INTERFACE + '.ChannelType': telepathy.CHANNEL_TYPE_CONTACT_LIST + telepathy.CHANNEL_INTERFACE + '.ChannelType': telepathy.CHANNEL_TYPE_FILE_TRANSFER, + telepathy.CHANNEL_INTERFACE + '.TargetHandleType': dbus.UInt32(telepathy.HANDLE_TYPE_CONTACT) } self._implement_channel_class( - telepathy.CHANNEL_TYPE_CONTACT_LIST, - self._get_list_channel, + telepathy.CHANNEL_TYPE_FILE_TRANSFER, + self._get_file_transfer_channel, fixed, [] ) @@ -67,6 +78,13 @@ class ChannelManager(tp.ChannelManager): chan = channel.text.TextChannel(self._conn, self, props, h) return chan + def _get_file_transfer_channel(self, props): + _, surpress_handler, h = self._get_type_requested_handle(props) + + _moduleLogger.debug('New file transfer channel') + chan = channel.debug_log.DebugLogChannel(self._conn, self, props, h) + return chan + def _get_media_channel(self, props): _, surpress_handler, h = self._get_type_requested_handle(props) -- 1.7.9.5