2013-11-20 21:12:21 +00:00
import collections
2019-01-09 22:59:03 +00:00
from . import HydrusConstants as HC
from . import HydrusDocumentHandling
from . import HydrusExceptions
from . import HydrusFileHandling
from . import HydrusFlashHandling
from . import HydrusImageHandling
from . import HydrusServerResources
2013-11-13 21:30:38 +00:00
import os
import random
2019-01-09 22:59:03 +00:00
from . import ServerFiles
2013-11-13 21:30:38 +00:00
import traceback
from twisted . internet import reactor , defer
from twisted . internet . threads import deferToThread
from twisted . protocols import amp
2019-01-09 22:59:03 +00:00
from . import HydrusData
from . import HydrusGlobals as HG
2015-11-11 21:20:41 +00:00
'''
2013-11-13 21:30:38 +00:00
class HydrusAMPCommand ( amp . Command ) :
errors = { }
2019-02-06 22:41:35 +00:00
errors [ HydrusExceptions . InsufficientCredentialsException ] = ' FORBIDDEN '
2013-11-13 21:30:38 +00:00
errors [ HydrusExceptions . NetworkVersionException ] = ' NETWORK_VERSION '
errors [ HydrusExceptions . NotFoundException ] = ' NOT_FOUND '
2019-02-06 22:41:35 +00:00
errors [ HydrusExceptions . MissingCredentialsException ] = ' PERMISSION '
2013-11-13 21:30:38 +00:00
errors [ HydrusExceptions . SessionException ] = ' SESSION '
errors [ Exception ] = ' EXCEPTION '
# IMFile, for aes-encrypted file transfers, as negotiated over otr messages
# file_transfer_id (so we can match up the correct aes key)
# file (this is complicated -- AMP should be little things, right? I need to check max packet size.)
# so, this should be blocks. a block_id and a block
2013-11-27 18:27:11 +00:00
# MMessageReceivedPing -- server to persistent client, saying someone just now sent you a message
2013-11-20 21:12:21 +00:00
class IMLoginPersistent ( HydrusAMPCommand ) :
2013-12-04 22:44:16 +00:00
arguments = [ ( ' network_version ' , amp . Integer ( ) ) , ( ' session_key ' , amp . String ( ) ) ]
2013-11-13 21:30:38 +00:00
2013-11-20 21:12:21 +00:00
class IMLoginTemporary ( HydrusAMPCommand ) :
2013-12-04 22:44:16 +00:00
arguments = [ ( ' network_version ' , amp . Integer ( ) ) , ( ' identifier ' , amp . String ( ) ) , ( ' name ' , amp . String ( ) ) ]
2013-11-20 21:12:21 +00:00
class IMMessageClient ( HydrusAMPCommand ) :
arguments = [ ( ' identifier_from ' , amp . String ( ) ) , ( ' name_from ' , amp . String ( ) ) , ( ' identifier_to ' , amp . String ( ) ) , ( ' name_to ' , amp . String ( ) ) , ( ' message ' , amp . String ( ) ) ]
class IMMessageServer ( HydrusAMPCommand ) :
arguments = [ ( ' identifier_to ' , amp . String ( ) ) , ( ' name_to ' , amp . String ( ) ) , ( ' message ' , amp . String ( ) ) ]
2013-11-13 21:30:38 +00:00
class IMSessionKey ( HydrusAMPCommand ) :
2013-11-27 18:27:11 +00:00
arguments = [ ( ' access_key ' , amp . String ( ) ) , ( ' name ' , amp . String ( ) ) ]
2013-11-13 21:30:38 +00:00
response = [ ( ' session_key ' , amp . String ( ) ) ]
class MPublicKey ( HydrusAMPCommand ) :
arguments = [ ( ' identifier ' , amp . String ( ) ) ]
response = [ ( ' public_key ' , amp . String ( ) ) ]
2013-12-04 22:44:16 +00:00
class HydrusAMP ( amp . AMP ) :
def _errbackHandleError ( self , failure ) :
2015-11-18 22:44:07 +00:00
HydrusData . Print ( failure . getTraceback ( ) )
2013-12-04 22:44:16 +00:00
normal_errors = [ ]
2019-02-06 22:41:35 +00:00
normal_errors . append ( HydrusExceptions . InsufficientCredentialsException )
2013-12-04 22:44:16 +00:00
normal_errors . append ( HydrusExceptions . NetworkVersionException )
normal_errors . append ( HydrusExceptions . NotFoundException )
2019-02-06 22:41:35 +00:00
normal_errors . append ( HydrusExceptions . MissingCredentialsException )
2013-12-04 22:44:16 +00:00
normal_errors . append ( HydrusExceptions . SessionException )
if failure . type in normal_errors : failure . raiseException ( )
else : raise Exception ( failure . getTraceback ( ) )
class MessagingClientProtocol ( HydrusAMP ) :
def im_message ( self , identifier_from , name_from , identifier_to , name_to , message ) :
2013-12-11 22:09:25 +00:00
def do_it ( gumpf ) :
2013-12-04 22:44:16 +00:00
2017-05-10 21:33:58 +00:00
HG . controller . pub ( ' im_message_received ' , identifier_from , name_from , identifier_to , name_to , message )
2013-12-04 22:44:16 +00:00
return { }
d = defer . Deferred ( )
d . addCallback ( do_it )
d . addErrback ( self . _errbackHandleError )
2013-12-11 22:09:25 +00:00
reactor . callLater ( 0 , d . callback , None )
2013-12-04 22:44:16 +00:00
return d
IMMessageClient . responder ( im_message )
def connectionLost ( self , reason ) :
# report to ui that the connection is lost
pass
class MessagingServiceProtocol ( HydrusAMP ) :
def __init__ ( self ) :
amp . AMP . __init__ ( self )
self . _identifier = None
self . _name = None
def _check_network_version ( self , network_version ) :
if network_version != HC . NETWORK_VERSION :
if network_version < HC . NETWORK_VERSION : message = ' Your client is out of date; please download the latest release. '
else : message = ' This server is out of date; please ask its admin to update to the latest release. '
2015-11-04 22:30:28 +00:00
message = ' Network version mismatch! This server \' s network version is ' + str ( HC . NETWORK_VERSION ) + ' , whereas your client \' s is ' + str ( network_version ) + ' ! ' + message
2013-12-04 22:44:16 +00:00
raise HydrusExceptions . NetworkVersionException ( message )
def im_login_persistent ( self , network_version , session_key ) :
def do_it ( gumpf ) :
self . _check_network_version ( network_version )
2017-05-10 21:33:58 +00:00
session_manager = HG . controller . GetManager ( ' messaging_sessions ' )
2013-12-04 22:44:16 +00:00
2014-08-27 22:15:22 +00:00
( identifier , name ) = session_manager . GetIdentityAndName ( self . factory . service_key , session_key )
2013-12-04 22:44:16 +00:00
self . _identifier = identifier
self . _name = name
self . factory . AddConnection ( True , self . _identifier , self . _name , self )
return { }
d = defer . Deferred ( )
d . addCallback ( do_it )
d . addErrback ( self . _errbackHandleError )
reactor . callLater ( 0 , d . callback , None )
return d
IMLoginPersistent . responder ( im_login_persistent )
def im_login_temporary ( self , network_version , identifier , name ) :
def do_it ( gumpf ) :
self . _check_network_version ( network_version )
self . _identifier = identifier
self . _name = name
self . factory . AddConnection ( False , self . _identifier , self . _name , self )
return { }
d = defer . Deferred ( )
d . addCallback ( do_it )
d . addErrback ( self . _errbackHandleError )
reactor . callLater ( 0 , d . callback , None )
return d
IMLoginTemporary . responder ( im_login_temporary )
def im_message ( self , identifier_to , name_to , message ) :
def do_it ( gumpf ) :
if self . _identifier is None or self . _name is None :
raise Exception ( ) # who the hell are you? pls temp login
connection = self . factory . GetConnection ( identifier_to , name_to )
d = connection . callRemote ( IMMessageClient , identifier_from = self . _identifier , name_from = self . _name , identifier_to = identifier_to , name_to = name_to , message = message )
return d
d = defer . Deferred ( )
d . addCallback ( do_it )
d . addErrback ( self . _errbackHandleError )
reactor . callLater ( 0 , d . callback , None )
return d
IMMessageServer . responder ( im_message )
def im_session_key ( self , access_key , name ) :
def catch_session_key ( session_key ) : return { ' session_key ' : session_key }
def do_it ( gumpf ) :
2017-05-10 21:33:58 +00:00
session_manager = HG . controller . GetManager ( ' messaging_sessions ' )
2013-12-04 22:44:16 +00:00
2014-08-27 22:15:22 +00:00
d = deferToThread ( session_manager . AddSession , self . factory . service_key , access_key , name )
2013-12-04 22:44:16 +00:00
d . addCallback ( catch_session_key )
return d
d = defer . Deferred ( )
d . addCallback ( do_it )
d . addErrback ( self . _errbackHandleError )
reactor . callLater ( 0 , d . callback , None )
return d
IMSessionKey . responder ( im_session_key )
def m_public_key ( self , identifier ) :
# this will not be useful until we have normal messaging sorted
public_key = ' public key '
return { ' public_key ' : public_key }
MPublicKey . responder ( m_public_key )
def connectionLost ( self , reason ) :
if self . _identifier is not None : self . factory . RemoveConnection ( self . _identifier , self . _name )
2017-03-02 02:14:56 +00:00
'''