<s> import os <EOL> from functools import partial <EOL> from collections import defaultdict <EOL> from irc3 . compat import asyncio <EOL> from irc3 . compat import isclass <EOL> from irc3 . compat import PY35 <EOL> from irc3 . utils import slugify <EOL> from irc3 . utils import maybedotted <EOL> from irc3 . dcc . client import DCCChat <EOL> from irc3 . dcc . client import DCCGet <EOL> if PY35 : <EOL> from irc3 . dcc . client import DCCSend <EOL> else : <EOL> try : <EOL> from irc3 . dcc . optim import DCCSend <EOL> except ImportError : <EOL> from irc3 . dcc . client import DCCSend <EOL> DCC_TYPES = ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) <EOL> class DCCManager ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , bot ) : <EOL> self . bot = bot <EOL> self . loop = bot . loop <EOL> self . config = cfg = bot . config . get ( '<STR_LIT>' , { } ) <EOL> self . config . update ( <EOL> send_limit_rate = int ( cfg . get ( '<STR_LIT>' , <NUM_LIT:0> ) ) , <EOL> send_block_size = int ( cfg . get ( '<STR_LIT>' , DCCSend . block_size ) ) <EOL> ) <EOL> self . connections = { } <EOL> self . protocols = { } <EOL> for klass in ( DCCChat , DCCGet , DCCSend ) : <EOL> n = klass . type <EOL> self . config . update ( { <EOL> n + '<STR_LIT>' : int ( cfg . get ( n + '<STR_LIT>' , <NUM_LIT:100> ) ) , <EOL> n + '<STR_LIT>' : int ( cfg . get ( n + '<STR_LIT>' , <NUM_LIT:1> ) ) , <EOL> n + '<STR_LIT>' : int ( cfg . get ( n + '<STR_LIT>' , <NUM_LIT> ) ) , <EOL> n + '<STR_LIT>' : int ( cfg . get ( n + '<STR_LIT>' , <NUM_LIT> * <NUM_LIT:5> ) ) , <EOL> } ) <EOL> klass = maybedotted ( self . config . get ( n + '<STR_LIT>' , klass ) ) <EOL> self . connections [ n ] = { '<STR_LIT>' : <NUM_LIT:0> , '<STR_LIT>' : defaultdict ( dict ) } <EOL> self . protocols [ n ] = klass <EOL> self . seeks = { } <EOL> def created ( self , protocol , future ) : <EOL> if protocol . port is None : <EOL> server = future . result ( ) <EOL> protocol . port = server . sockets [ <NUM_LIT:0> ] . getsockname ( ) [ <NUM_LIT:1> ] <EOL> protocol . idle_handle = self . loop . call_later ( <EOL> self . config [ protocol . type + '<STR_LIT>' ] , <EOL> server . close ) <EOL> ctcp_msg = protocol . ctcp . format ( protocol ) <EOL> self . bot . ctcp ( protocol . mask . nick , ctcp_msg ) <EOL> else : <EOL> transport , protocol = future . result ( ) <EOL> protocol . idle_handle = self . loop . call_later ( <EOL> self . config [ protocol . type + '<STR_LIT>' ] , <EOL> protocol . close ) <EOL> info = self . connections [ protocol . type ] <EOL> info [ '<STR_LIT>' ] += <NUM_LIT:1> <EOL> info [ '<STR_LIT>' ] [ protocol . mask ] [ protocol . port ] = protocol <EOL> protocol . ready . set_result ( protocol ) <EOL> def create ( self , name_or_class , mask , filepath = None , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> if isclass ( name_or_class ) : <EOL> name = name_or_class . type <EOL> protocol = name_or_class <EOL> else : <EOL> name = name_or_class <EOL> protocol = self . protocols [ name ] <EOL> assert name in DCC_TYPES <EOL> if filepath : <EOL> kwargs . setdefault ( '<STR_LIT>' , <EOL> self . config [ '<STR_LIT>' ] ) <EOL> kwargs [ '<STR_LIT>' ] = filepath <EOL> if protocol . type == DCCSend . type : <EOL> kwargs . setdefault ( '<STR_LIT>' , <NUM_LIT:0> ) <EOL> kwargs . update ( <EOL> filename_safe = slugify ( os . path . basename ( filepath ) ) , <EOL> filesize = os . path . getsize ( filepath ) , <EOL> ) <EOL> elif protocol . type == DCCGet . type : <EOL> try : <EOL> offset = os . path . getsize ( filepath ) <EOL> except OSError : <EOL> offset = <NUM_LIT:0> <EOL> kwargs . setdefault ( '<STR_LIT>' , offset ) <EOL> kwargs . setdefault ( '<STR_LIT>' , False ) <EOL> kwargs . setdefault ( '<STR_LIT:port>' , None ) <EOL> f = protocol ( <EOL> mask = mask , ip = int ( self . bot . ip ) , <EOL> bot = self . bot , loop = self . loop , ** kwargs ) <EOL> if kwargs [ '<STR_LIT:port>' ] : <EOL> task = asyncio . async ( <EOL> self . loop . create_connection ( f . factory , f . host , f . port ) , <EOL> loop = self . loop ) <EOL> task . add_done_callback ( partial ( self . created , f ) ) <EOL> else : <EOL> task = asyncio . async ( <EOL> self . loop . create_server ( <EOL> f . factory , '<STR_LIT>' , <NUM_LIT:0> , backlog = <NUM_LIT:1> ) , <EOL> loop = self . loop ) <EOL> task . add_done_callback ( partial ( self . created , f ) ) <EOL> return f <EOL> def resume ( self , mask , filename , port , pos ) : <EOL> """<STR_LIT>""" <EOL> self . connections [ '<STR_LIT>' ] [ '<STR_LIT>' ] [ mask ] [ port ] . offset = pos <EOL> message = '<STR_LIT>' % ( filename , port , pos ) <EOL> self . bot . ctcp ( mask , message ) <EOL> def is_allowed ( self , name_or_class , mask ) : <EOL> """<STR_LIT>""" <EOL> if isclass ( name_or_class ) : <EOL> name = name_or_class . type <EOL> else : <EOL> name = name_or_class <EOL> info = self . connections [ name ] <EOL> limit = self . config [ name + '<STR_LIT>' ] <EOL> if limit and info [ '<STR_LIT>' ] >= limit : <EOL> msg = ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) % name . upper ( ) <EOL> self . bot . notice ( mask , msg ) <EOL> return False <EOL> if mask not in info [ '<STR_LIT>' ] : <EOL> return True <EOL> limit = self . config [ name + '<STR_LIT>' ] <EOL> if limit and info [ '<STR_LIT>' ] [ mask ] >= limit : <EOL> msg = ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> ) % name . upper ( ) <EOL> self . bot . notice ( mask , msg ) <EOL> return False <EOL> return True </s>
