Forgot to log exceptions for these calls, no wonder it was harder to find the issue
[theonering] / src / channel / debug_log.py
1 from __future__ import with_statement
2
3 import os
4 import socket
5 import logging
6
7 import telepathy
8
9 import constants
10 import tp
11 import util.go_utils as gobject_utils
12 import util.misc as misc_utils
13
14
15 _moduleLogger = logging.getLogger(__name__)
16
17
18 class DebugLogChannel(tp.ChannelTypeFileTransfer):
19
20         def __init__(self, connection, manager, props, contactHandle):
21                 self.__manager = manager
22                 self.__props = props
23                 self.__otherHandle = contactHandle
24                 self.__socket = None
25                 self.__socketName = ""
26                 self.__delayWrite = gobject_utils.Timeout(self._on_write)
27
28                 tp.ChannelTypeFileTransfer.__init__(self, connection, manager, props)
29
30                 dbus_interface = telepathy.CHANNEL_TYPE_FILE_TRANSFER
31                 self._implement_property_get(
32                         dbus_interface,
33                         {
34                                 'State': self.get_state,
35                                 "ContentType": self.get_content_type,
36                                 "Filename": self.get_filename,
37                                 "Size": self.get_state,
38                                 "Description": self.get_description,
39                                 "AvailableSocketTypes": self.get_available_socket_types,
40                                 "TransferredBytes": self.get_transferred_bytes,
41                                 "InitialOffset": self.get_initial_offset,
42                         },
43                 )
44
45                 # grab a snapshot of the log so that we are always in a consistent
46                 # state between calls
47                 with open(constants._user_logpath_, "r") as f:
48                         logLines = f.xreadlines()
49                         self._log = "".join(logLines)
50                 self._transferredBytes = 0
51
52                 self._state = telepathy.constants.FILE_TRANSFER_STATE_PENDING
53                 self.FileTransferStateChanged(
54                         self._state,
55                         telepathy.constants.FILE_TRANSFER_STATE_CHANGE_REASON_NONE,
56                 )
57
58         def get_state(self):
59                 return self._state
60
61         def get_content_type(self):
62                 return "application/octet-stream"
63
64         def get_filename(self):
65                 return "%s.log" % constants._telepathy_implementation_name_
66
67         def get_size(self):
68                 return len(self._log)
69
70         def get_description(self):
71                 return "Debug log for The One Ring"
72
73         def get_available_socket_types(self):
74                 return {
75                         telepathy.constants.SOCKET_ADDRESS_TYPE_UNIX: [
76                                 telepathy.constants.SOCKET_ACCESS_CONTROL_LOCALHOST,
77                                 telepathy.constants.SOCKET_ACCESS_CONTROL_CREDENTIALS,
78                         ],
79                 }
80
81         def get_transferred_bytes(self):
82                 return self._transferredBytes
83
84         def get_initial_offset(self):
85                 return 0
86
87         @misc_utils.log_exception(_moduleLogger)
88         def AcceptFile(self, addressType, accessControl, accessControlParam, offset):
89                 # @bug All wrong
90                 _moduleLogger.info("%r %r %r %r" % (addressType, accessControl, accessControlParam, offset))
91                 assert not self.__socketName, self.__socketName
92                 self.__socketName = os.tempnam()
93
94                 assert self.__socket is None, self.__socket
95                 self.__socket = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
96                 self.__socket.bind(self.__socketName)
97
98                 self._state = telepathy.constants.FILE_TRANSFER_STATE_ACCEPTED
99                 self.FileTransferStateChanged(
100                         self._state,
101                         telepathy.constants.FILE_TRANSFER_STATE_CHANGE_REASON_REQUESTED,
102                 )
103
104                 self.__delayWrite.start(seconds=0)
105
106                 return self.__socketName
107
108         @misc_utils.log_exception(_moduleLogger)
109         def ProvideFile(self, addressType, accessControl, accessControlParam):
110                 raise telepathy.errors.NotImplemented("Cannot send outbound files")
111
112         @misc_utils.log_exception(_moduleLogger)
113         def Close(self):
114                 self.close()
115
116         def close(self):
117                 _moduleLogger.debug("Closing log")
118                 if self.__socket is not None:
119                         self.__socket.close()
120                 tp.ChannelTypeFileTransfer.Close(self)
121                 self.remove_from_connection()
122
123         @misc_utils.log_exception(_moduleLogger)
124         def _on_write(self):
125                 self.__socket.listen(1)
126                 conn, addr = self.__socket.accept()
127
128                 self.InitialOffsetDefined(0)
129                 self._state = telepathy.constants.FILE_TRANSFER_STATE_OPEN
130                 self.FileTransferStateChanged(
131                         self._state,
132                         telepathy.constants.FILE_TRANSFER_STATE_CHANGE_REASON_NONE,
133                 )
134
135                 conn.send(self._log)
136
137                 self._transferredBytes = len(self._log)
138                 self.TransferredBytesChanged(self._transferredBytes)
139
140                 self._state = telepathy.constants.FILE_TRANSFER_STATE_COMPLETED
141                 self.FileTransferStateChanged(
142                         self._state,
143                         telepathy.constants.FILE_TRANSFER_STATE_CHANGE_REASON_NONE,
144                 )