| Total Complexity | 66 | 
| Total Lines | 231 | 
| Duplicated Lines | 0 % | 
Complex classes like doorpi.sipphone.linphone_lib.LinphoneCallbacks often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
| 1 | #!/usr/bin/env python  | 
            ||
| 12 | class LinphoneCallbacks:  | 
            ||
| 13 | |||
| 14 | @property  | 
            ||
| 15 |     def used_callbacks(self): return { | 
            ||
| 16 | #http://www.linphone.org/docs/liblinphone/struct__LinphoneCoreVTable.html  | 
            ||
| 17 | #'global_state_changed': self.global_state_changed, #Notifies global state changes  | 
            ||
| 18 | #'registration_state_changed': self.registration_state_changed, #Notifies registration state changes  | 
            ||
| 19 | 'call_state_changed': self.call_state_changed, #Notifies call state changes  | 
            ||
| 20 | #'notify_presence_received': self.notify_presence_received, #Notify received presence events  | 
            ||
| 21 | #'new_subscription_requested': self.new_subscription_requested, #Notify about pending presence subscription request  | 
            ||
| 22 | #'auth_info_requested': self.auth_info_requested, #Ask the application some authentication information  | 
            ||
| 23 | #'call_log_updated': self.call_log_updated, #Notifies that call log list has been updated  | 
            ||
| 24 | #'message_received': self.message_received, #a message is received, can be text or external body  | 
            ||
| 25 | #'is_composing_received': self.is_composing_received, #An is-composing notification has been received  | 
            ||
| 26 | 'dtmf_received': self.dtmf_received, #A dtmf has been received received  | 
            ||
| 27 | #'refer_received': self.refer_received, #An out of call refer was received  | 
            ||
| 28 | #'call_encryption_changed': self.call_encryption_changed, #Notifies on change in the encryption of call streams  | 
            ||
| 29 | #'transfer_state_changed': self.transfer_state_changed, #Notifies when a transfer is in progress  | 
            ||
| 30 | #'buddy_info_updated': self.buddy_info_updated, #a LinphoneFriend's BuddyInfo has changed  | 
            ||
| 31 | #'call_stats_updated': self.call_stats_updated, #Notifies on refreshing of call's statistics.  | 
            ||
| 32 | #'info_received': self.info_received, #Notifies an incoming informational message received.  | 
            ||
| 33 | #'subscription_state_changed': self.subscription_state_changed, #Notifies subscription state change  | 
            ||
| 34 | #'notify_received': self.notify_received, #Notifies a an event notification, see linphone_core_subscribe()  | 
            ||
| 35 | #'configuring_status': self.configuring_status, #Notifies publish state change (only from LinphoneEvent api)  | 
            ||
| 36 | #'network_reachable': self.network_reachable, #Callback to report IP network status (I.E up/down )  | 
            ||
| 37 | #'log_collection_upload_state_changed': self.log_collection_upload_state_changed, #Callback to upload collected logs  | 
            ||
| 38 | #'log_collection_upload_progress_indication': self.log_collection_upload_progress_indication #Callback to indicate log collection upload progress  | 
            ||
| 39 | }  | 
            ||
| 40 | |||
| 41 | @property  | 
            ||
| 42 |     def whitelist(self): return DoorPi().config.get_keys('AdminNumbers') | 
            ||
| 43 | |||
| 44 | def is_admin_number(self, remote_uri):  | 
            ||
| 45 |         logger.debug("is_admin_number (%s)",remote_uri) | 
            ||
| 46 | for admin_number in self.whitelist:  | 
            ||
| 47 | if admin_number == "*":  | 
            ||
| 48 |                 logger.info("admin numbers are deactivated by using '*' as single number") | 
            ||
| 49 | return True  | 
            ||
| 50 | if "sip:"+admin_number+"@" in remote_uri:  | 
            ||
| 51 |                 logger.debug("%s is adminnumber %s", remote_uri, admin_number) | 
            ||
| 52 | return True  | 
            ||
| 53 | if "sip:"+admin_number is remote_uri:  | 
            ||
| 54 |                 logger.debug("%s is adminnumber %s", remote_uri, admin_number) | 
            ||
| 55 | return True  | 
            ||
| 56 |         logger.debug("%s is not an adminnumber", remote_uri) | 
            ||
| 57 | return False  | 
            ||
| 58 | |||
| 59 | __DTMF = ''  | 
            ||
| 60 | __possible_DTMF = []  | 
            ||
| 61 | |||
| 62 | def __init__(self):  | 
            ||
| 63 |         logger.debug("__init__") | 
            ||
| 64 | |||
| 65 | self._last_number_of_calls = 0  | 
            ||
| 66 | |||
| 67 |         DoorPi().event_handler.register_action('OnSipPhoneDestroy', self.destroy) | 
            ||
| 68 | |||
| 69 |         DoorPi().event_handler.register_event('OnCallMediaStateChange', __name__) | 
            ||
| 70 |         DoorPi().event_handler.register_event('OnMediaRequired', __name__) | 
            ||
| 71 |         DoorPi().event_handler.register_event('OnMediaNotRequired', __name__) | 
            ||
| 72 | |||
| 73 |         DoorPi().event_handler.register_event('OnCallStateChange', __name__) | 
            ||
| 74 |         DoorPi().event_handler.register_event('OnCallStateConnect', __name__) | 
            ||
| 75 |         DoorPi().event_handler.register_event('AfterCallStateConnect', __name__) | 
            ||
| 76 |         DoorPi().event_handler.register_event('OnCallStateDisconnect', __name__) | 
            ||
| 77 |         DoorPi().event_handler.register_event('AfterCallStateDisconnect', __name__) | 
            ||
| 78 |         DoorPi().event_handler.register_event('OnCallStateDismissed', __name__) | 
            ||
| 79 |         DoorPi().event_handler.register_event('OnCallStateReject', __name__) | 
            ||
| 80 |         DoorPi().event_handler.register_event('OnCallStart', __name__) | 
            ||
| 81 |         DoorPi().event_handler.register_event('OnDTMF', __name__) | 
            ||
| 82 | |||
| 83 |         self.__possible_DTMF = DoorPi().config.get_keys('DTMF') | 
            ||
| 84 | for DTMF in self.__possible_DTMF:  | 
            ||
| 85 |             DoorPi().event_handler.register_event('OnDTMF_'+DTMF, __name__) | 
            ||
| 86 | |||
| 87 |         DoorPi().event_handler.register_event('OnCallStart', __name__) | 
            ||
| 88 |         DoorPi().event_handler.register_event('BeforeCallIncoming', __name__) | 
            ||
| 89 |         DoorPi().event_handler.register_event('OnCallReconnect', __name__) | 
            ||
| 90 |         DoorPi().event_handler.register_event('AfterCallReconnect', __name__) | 
            ||
| 91 |         DoorPi().event_handler.register_event('OnCallBusy', __name__) | 
            ||
| 92 |         DoorPi().event_handler.register_event('AfterCallBusy', __name__) | 
            ||
| 93 |         DoorPi().event_handler.register_event('OnCallIncoming', __name__) | 
            ||
| 94 |         DoorPi().event_handler.register_event('AfterCallIncoming', __name__) | 
            ||
| 95 |         DoorPi().event_handler.register_event('OnCallReject', __name__) | 
            ||
| 96 |         DoorPi().event_handler.register_event('AfterCallReject', __name__) | 
            ||
| 97 |         #DoorPi().event_handler.register_event('AfterAccountRegState', __name__) | 
            ||
| 98 | |||
| 99 |         DoorPi().event_handler('OnCallStart', __name__) | 
            ||
| 100 | |||
| 101 | def destroy(self):  | 
            ||
| 102 |         logger.debug("destroy") | 
            ||
| 103 | DoorPi().event_handler.unregister_source(__name__, True)  | 
            ||
| 104 | |||
| 105 | def global_state_changed(self, core, global_state, message): pass  | 
            ||
| 106 | def registration_state_changed(self, core, linphone_proxy_config, state, message): pass  | 
            ||
| 107 | def call_state_changed(self, core, call, call_state, message):  | 
            ||
| 108 | self.call_state_changed_handle(core, call, call_state, message)  | 
            ||
| 109 | |||
| 110 | if core.calls_nb > 0 and self._last_number_of_calls == 0:  | 
            ||
| 111 |             DoorPi().event_handler('OnMediaRequired', __name__) | 
            ||
| 112 | elif self._last_number_of_calls is not core.calls_nb:  | 
            ||
| 113 |             DoorPi().event_handler('OnMediaNotRequired', __name__) | 
            ||
| 114 | self._last_number_of_calls = core.calls_nb  | 
            ||
| 115 | |||
| 116 | def call_state_changed_handle(self, core, call, call_state, message):  | 
            ||
| 117 |         logger.debug("call_state_changed (%s - %s)", call_state, message) | 
            ||
| 118 | |||
| 119 | remote_uri = call.remote_address.as_string_uri_only()  | 
            ||
| 120 | |||
| 121 |         DoorPi().event_handler('OnCallStateChange', __name__, { | 
            ||
| 122 | 'remote_uri': remote_uri,  | 
            ||
| 123 | 'call_state': call_state,  | 
            ||
| 124 | 'state': message  | 
            ||
| 125 | })  | 
            ||
| 126 | |||
| 127 | if call_state == linphone.CallState.Idle:  | 
            ||
| 128 | pass  | 
            ||
| 129 | elif call_state == linphone.CallState.IncomingReceived:  | 
            ||
| 130 |             DoorPi().event_handler('BeforeCallIncoming', __name__, {'remote_uri': remote_uri}) | 
            ||
| 131 | if core.current_call and core.current_call.state > linphone.CallState.IncomingReceived:  | 
            ||
| 132 |                 logger.debug("Incoming call while another call is active") | 
            ||
| 133 |                 logger.debug("- incoming.remote_uri: %s", call) | 
            ||
| 134 |                 logger.debug("- current.remote_uri : %s", core.current_call) | 
            ||
| 135 | |||
| 136 | if core.current_call.remote_address.as_string_uri_only() == remote_uri:  | 
            ||
| 137 |                     logger.info("Current call is incoming call - quitting current and connecting to incoming. Maybe connection reset?") | 
            ||
| 138 |                     DoorPi().event_handler('OnCallReconnect', __name__, {'remote_uri': remote_uri}) | 
            ||
| 139 | core.terminate_call(core.current_call)  | 
            ||
| 140 | DoorPi().sipphone.reset_call_start_datetime()  | 
            ||
| 141 | core.accept_call_with_params(call, DoorPi().sipphone.base_config)  | 
            ||
| 142 |                     DoorPi().event_handler('AfterCallReconnect', __name__) | 
            ||
| 143 | return  | 
            ||
| 144 | else:  | 
            ||
| 145 | if self.is_admin_number(remote_uri):  | 
            ||
| 146 |                         logger.info("Incoming and current call are different - incoming is AdminNumber, so hanging up current call") | 
            ||
| 147 |                         DoorPi().event_handler('OnCallIncoming', __name__, {'remote_uri': remote_uri}) | 
            ||
| 148 | core.terminate_call(core.current_call)  | 
            ||
| 149 | DoorPi().sipphone.reset_call_start_datetime()  | 
            ||
| 150 | core.accept_call_with_params(call, DoorPi().sipphone.base_config)  | 
            ||
| 151 |                         DoorPi().event_handler('AfterCallIncoming', __name__, {'remote_uri': remote_uri}) | 
            ||
| 152 | return  | 
            ||
| 153 | else:  | 
            ||
| 154 |                         logger.info("Incoming and current call are different - sending busy signal to incoming call") | 
            ||
| 155 |                         DoorPi().event_handler('OnCallBusy', __name__, {'remote_uri': remote_uri}) | 
            ||
| 156 | core.decline_call(call, linphone.Reason.Busy)  | 
            ||
| 157 |                         DoorPi().event_handler('AfterCallBusy', __name__) | 
            ||
| 158 | return  | 
            ||
| 159 | if self.is_admin_number(remote_uri):  | 
            ||
| 160 |                 DoorPi().event_handler('OnCallIncoming', __name__, {'remote_uri': remote_uri}) | 
            ||
| 161 | DoorPi().sipphone.reset_call_start_datetime()  | 
            ||
| 162 | core.accept_call_with_params(call, DoorPi().sipphone.base_config)  | 
            ||
| 163 |                 DoorPi().event_handler('AfterCallIncoming', __name__, {'remote_uri': remote_uri}) | 
            ||
| 164 | return  | 
            ||
| 165 | else:  | 
            ||
| 166 |                 DoorPi().event_handler('OnCallReject', __name__) | 
            ||
| 167 | core.decline_call(call, linphone.Reason.Forbidden) #Declined  | 
            ||
| 168 |                 DoorPi().event_handler('AfterCallReject', __name__) | 
            ||
| 169 | return  | 
            ||
| 170 | elif call_state == linphone.CallState.OutgoingInit:  | 
            ||
| 171 | pass  | 
            ||
| 172 | elif call_state == linphone.CallState.OutgoingProgress:  | 
            ||
| 173 | pass  | 
            ||
| 174 | elif call_state == linphone.CallState.OutgoingRinging:  | 
            ||
| 175 | pass  | 
            ||
| 176 | elif call_state == linphone.CallState.OutgoingEarlyMedia:  | 
            ||
| 177 |             DoorPi().event_handler('OnCallMediaStateChange', __name__) | 
            ||
| 178 | elif call_state == linphone.CallState.Connected:  | 
            ||
| 179 |             DoorPi().event_handler('OnCallStateConnect', __name__) | 
            ||
| 180 | elif call_state == linphone.CallState.StreamsRunning:  | 
            ||
| 181 |             DoorPi().event_handler('AfterCallStateConnect', __name__) | 
            ||
| 182 |             DoorPi().event_handler('OnCallMediaStateChange', __name__) | 
            ||
| 183 | elif call_state == linphone.CallState.Pausing:  | 
            ||
| 184 | pass  | 
            ||
| 185 | elif call_state == linphone.CallState.Paused:  | 
            ||
| 186 |             DoorPi().event_handler('OnCallMediaStateChange', __name__) | 
            ||
| 187 | elif call_state == linphone.CallState.Resuming:  | 
            ||
| 188 |             DoorPi().event_handler('OnCallStateConnect', __name__) | 
            ||
| 189 |             DoorPi().event_handler('OnCallMediaStateChange', __name__) | 
            ||
| 190 | elif call_state == linphone.CallState.Refered:  | 
            ||
| 191 | pass  | 
            ||
| 192 | elif call_state == linphone.CallState.Error:  | 
            ||
| 193 |             if message == "Busy here": DoorPi().event_handler('OnCallStateDismissed', __name__) | 
            ||
| 194 | elif call_state == linphone.CallState.End:  | 
            ||
| 195 |             if message == "Call declined.": DoorPi().event_handler('OnCallStateReject', __name__) | 
            ||
| 196 |             DoorPi().event_handler('OnCallStateDisconnect', __name__) | 
            ||
| 197 | elif call_state == linphone.CallState.PausedByRemote:  | 
            ||
| 198 | pass  | 
            ||
| 199 | elif call_state == linphone.CallState.UpdatedByRemote:  | 
            ||
| 200 | pass  | 
            ||
| 201 | elif call_state == linphone.CallState.IncomingEarlyMedia:  | 
            ||
| 202 |             DoorPi().event_handler('OnCallMediaStateChange', __name__) | 
            ||
| 203 | elif call_state == linphone.CallState.Updating:  | 
            ||
| 204 |             DoorPi().event_handler('OnCallStateConnect', __name__) | 
            ||
| 205 |             DoorPi().event_handler('OnCallMediaStateChange', __name__) | 
            ||
| 206 | elif call_state == linphone.CallState.Released:  | 
            ||
| 207 | pass  | 
            ||
| 208 | elif call_state == linphone.CallState.EarlyUpdatedByRemote:  | 
            ||
| 209 | pass  | 
            ||
| 210 | elif call_state == linphone.CallState.EarlyUpdating:  | 
            ||
| 211 | pass  | 
            ||
| 212 | def notify_presence_received(self, core, linphone_friend): pass  | 
            ||
| 213 | def new_subscription_requested(self, core, linphone_friend, url): pass  | 
            ||
| 214 | def auth_info_requested(self, core, realm, username): pass  | 
            ||
| 215 | def call_log_updated(self, core, new_call_log_entry): pass  | 
            ||
| 216 | def message_received(self, core, linphone_chat_room, message): pass  | 
            ||
| 217 | def is_composing_received(self, core, linphone_chat_room): pass  | 
            ||
| 218 | def dtmf_received(self, core, call, digits):  | 
            ||
| 219 |         logger.debug("on_dtmf_digit (%s)", str(digits)) | 
            ||
| 220 | digits = chr(digits)  | 
            ||
| 221 |         DoorPi().event_handler('OnDTMF', __name__, {'digits':digits}) | 
            ||
| 222 | self.__DTMF += str(digits)  | 
            ||
| 223 | for DTMF in self.__possible_DTMF:  | 
            ||
| 224 | if self.__DTMF.endswith(DTMF[1:-1]):  | 
            ||
| 225 |                 DoorPi().event_handler('OnDTMF_'+DTMF+'', __name__, { | 
            ||
| 226 | 'remote_uri': str(call.remote_address.as_string_uri_only()),  | 
            ||
| 227 | 'DTMF': str(self.__DTMF)  | 
            ||
| 228 | })  | 
            ||
| 229 | def refer_received(self, core, refer_to): pass  | 
            ||
| 230 | def call_encryption_changed(self, core, call, on, authentication_token): pass  | 
            ||
| 231 | def transfer_state_changed(self, core, call, transfer_state): pass  | 
            ||
| 232 | def buddy_info_updated(self, core, linphone_friend): pass  | 
            ||
| 233 | def call_stats_updated(self, core, call, stats): pass  | 
            ||
| 234 | def info_received(self, core, call, message): pass  | 
            ||
| 235 | def subscription_state_changed(self, core, linphone_event, linphone_subscription_state): pass  | 
            ||
| 236 | def notify_received(self, core, linphone_event, linphone_subscription_state, linphone_body): pass  | 
            ||
| 237 | def configuring_status(self, core, linphone_configuring_state, message): pass  | 
            ||
| 238 | def network_reachable(self, core, reachable): pass  | 
            ||
| 239 | def log_collection_upload_state_changed(self, core, linphone_core_log_collection_upload_state, info): pass  | 
            ||
| 240 | def log_collection_upload_progress_indication(self, core, offset, total): pass  | 
            ||
| 241 | |||
| 242 | __del__ = destroy  |