<s> import binascii <EOL> import logging <EOL> import tkMessageBox <EOL> from Crypto import Random <EOL> from lbrynet . conf import MIN_BLOB_DATA_PAYMENT_RATE <EOL> from lbrynet . core import StreamDescriptor <EOL> from lbrynet . core . Error import UnknownNameError , UnknownStreamTypeError , InvalidStreamDescriptorError <EOL> from lbrynet . core . Error import InvalidStreamInfoError <EOL> from lbrynet . core . LBRYcrdWallet import LBRYcrdWallet <EOL> from lbrynet . core . PaymentRateManager import PaymentRateManager <EOL> from lbrynet . core . Session import LBRYSession <EOL> from lbrynet . core . StreamDescriptor import StreamDescriptorIdentifier <EOL> from lbrynet . core . server . BlobAvailabilityHandler import BlobAvailabilityHandlerFactory <EOL> from lbrynet . core . server . BlobRequestHandler import BlobRequestHandlerFactory <EOL> from lbrynet . core . server . ServerProtocol import ServerProtocolFactory <EOL> from lbrynet . lbryfile . LBRYFileMetadataManager import TempLBRYFileMetadataManager <EOL> from lbrynet . lbryfile . StreamDescriptor import LBRYFileStreamType <EOL> from lbrynet . lbryfile . client . LBRYFileDownloader import LBRYFileSaverFactory , LBRYFileOpenerFactory <EOL> from lbrynet . lbryfile . client . LBRYFileOptions import add_lbry_file_to_sd_identifier <EOL> import os <EOL> import requests <EOL> import shutil <EOL> import sys <EOL> from twisted . internet import threads , defer , task <EOL> log = logging . getLogger ( __name__ ) <EOL> class LBRYDownloader ( object ) : <EOL> def __init__ ( self ) : <EOL> self . session = None <EOL> self . known_dht_nodes = [ ( '<STR_LIT>' , <NUM_LIT> ) ] <EOL> self . db_dir = os . path . join ( os . path . expanduser ( "<STR_LIT>" ) , "<STR_LIT>" ) <EOL> self . blobfile_dir = os . path . join ( self . db_dir , "<STR_LIT>" ) <EOL> self . peer_port = <NUM_LIT> <EOL> self . dht_node_port = <NUM_LIT> <EOL> self . run_server = True <EOL> self . first_run = False <EOL> self . current_db_revision = <NUM_LIT:1> <EOL> if os . name == "<STR_LIT>" : <EOL> from lbrynet . winhelpers . knownpaths import get_path , FOLDERID , UserHandle <EOL> self . download_directory = get_path ( FOLDERID . Downloads , UserHandle . current ) <EOL> self . wallet_dir = os . path . join ( get_path ( FOLDERID . RoamingAppData , UserHandle . current ) , "<STR_LIT>" ) <EOL> else : <EOL> if sys . platform == '<STR_LIT>' : <EOL> self . download_directory = os . path . join ( os . path . expanduser ( "<STR_LIT>" ) , "<STR_LIT>" ) <EOL> self . wallet_dir = os . path . join ( os . path . expanduser ( "<STR_LIT>" ) , "<STR_LIT>" ) <EOL> else : <EOL> self . download_directory = os . getcwd ( ) <EOL> self . wallet_dir = os . path . join ( os . path . expanduser ( "<STR_LIT>" ) , "<STR_LIT>" ) <EOL> self . wallet_conf = os . path . join ( self . wallet_dir , "<STR_LIT>" ) <EOL> self . wallet_user = None <EOL> self . wallet_password = None <EOL> self . sd_identifier = StreamDescriptorIdentifier ( ) <EOL> self . wallet_rpc_port = <NUM_LIT> <EOL> self . download_deferreds = [ ] <EOL> self . stream_frames = [ ] <EOL> self . default_blob_data_payment_rate = MIN_BLOB_DATA_PAYMENT_RATE <EOL> self . use_upnp = True <EOL> self . start_lbrycrdd = True <EOL> if os . name == "<STR_LIT>" : <EOL> self . lbrycrdd_path = "<STR_LIT>" <EOL> else : <EOL> self . lbrycrdd_path = None <EOL> self . default_lbrycrdd_path = "<STR_LIT>" <EOL> self . delete_blobs_on_remove = True <EOL> self . blob_request_payment_rate_manager = None <EOL> def start ( self ) : <EOL> d = self . _load_conf_options ( ) <EOL> d . addCallback ( lambda _ : threads . deferToThread ( self . _create_directory ) ) <EOL> d . addCallback ( lambda _ : self . _check_db_migration ( ) ) <EOL> d . addCallback ( lambda _ : self . _get_session ( ) ) <EOL> d . addCallback ( lambda _ : self . _setup_stream_info_manager ( ) ) <EOL> d . addCallback ( lambda _ : self . _setup_stream_identifier ( ) ) <EOL> d . addCallback ( lambda _ : self . start_server ( ) ) <EOL> return d <EOL> def stop ( self ) : <EOL> dl = defer . DeferredList ( self . download_deferreds ) <EOL> for stream_frame in self . stream_frames : <EOL> stream_frame . cancel_func ( ) <EOL> if self . session is not None : <EOL> dl . addBoth ( lambda _ : self . stop_server ( ) ) <EOL> dl . addBoth ( lambda _ : self . session . shut_down ( ) ) <EOL> return dl <EOL> def get_new_address ( self ) : <EOL> return self . session . wallet . get_new_address ( ) <EOL> def _check_db_migration ( self ) : <EOL> old_revision = <NUM_LIT:0> <EOL> db_revision_file = os . path . join ( self . db_dir , "<STR_LIT>" ) <EOL> if os . path . exists ( db_revision_file ) : <EOL> old_revision = int ( open ( db_revision_file ) . read ( ) . strip ( ) ) <EOL> if old_revision < self . current_db_revision : <EOL> if os . name == "<STR_LIT>" : <EOL> import subprocess <EOL> import sys <EOL> def run_migrator ( ) : <EOL> migrator_exe = os . path . join ( os . path . dirname ( os . path . abspath ( sys . argv [ <NUM_LIT:0> ] ) ) , <EOL> "<STR_LIT>" , "<STR_LIT>" ) <EOL> print "<STR_LIT>" , migrator_exe <EOL> si = subprocess . STARTUPINFO <EOL> si . dwFlags = subprocess . STARTF_USESHOWWINDOW <EOL> si . wShowWindow = subprocess . SW_HIDE <EOL> print "<STR_LIT>" <EOL> migrator_proc = subprocess . Popen ( [ migrator_exe , self . db_dir , str ( old_revision ) , <EOL> str ( self . current_db_revision ) ] , startupinfo = si ) <EOL> print "<STR_LIT>" <EOL> migrator_proc . wait ( ) <EOL> print "<STR_LIT>" <EOL> return threads . deferToThread ( run_migrator ) <EOL> else : <EOL> from lbrynet . db_migrator import dbmigrator <EOL> return threads . deferToThread ( dbmigrator . migrate_db , self . db_dir , old_revision , <EOL> self . current_db_revision ) <EOL> return defer . succeed ( True ) <EOL> def _load_conf_options ( self ) : <EOL> def get_lbrycrdd_path_conf_file ( ) : <EOL> if os . name == "<STR_LIT>" : <EOL> return "<STR_LIT>" <EOL> lbrycrdd_path_conf_path = os . path . join ( os . path . expanduser ( "<STR_LIT>" ) , "<STR_LIT>" ) <EOL> if not os . path . exists ( lbrycrdd_path_conf_path ) : <EOL> return "<STR_LIT>" <EOL> lbrycrdd_path_conf = open ( lbrycrdd_path_conf_path ) <EOL> lines = lbrycrdd_path_conf . readlines ( ) <EOL> return lines <EOL> d = threads . deferToThread ( get_lbrycrdd_path_conf_file ) <EOL> def load_lbrycrdd_path ( conf ) : <EOL> for line in conf : <EOL> if len ( line . strip ( ) ) and line . strip ( ) [ <NUM_LIT:0> ] != "<STR_LIT:#>" : <EOL> self . lbrycrdd_path = line . strip ( ) <EOL> d . addCallback ( load_lbrycrdd_path ) <EOL> def get_configuration_file ( ) : <EOL> if os . name == "<STR_LIT>" : <EOL> lbry_conf_path = "<STR_LIT>" <EOL> if not os . path . exists ( lbry_conf_path ) : <EOL> log . debug ( "<STR_LIT>" ) <EOL> return "<STR_LIT>" <EOL> else : <EOL> lbry_conf_path = os . path . join ( os . path . expanduser ( "<STR_LIT>" ) , "<STR_LIT>" ) <EOL> if not os . path . exists ( lbry_conf_path ) : <EOL> clean_conf_path = os . path . join ( os . path . dirname ( __file__ ) , "<STR_LIT>" ) <EOL> shutil . copy ( clean_conf_path , lbry_conf_path ) <EOL> lbry_conf = open ( lbry_conf_path ) <EOL> log . debug ( "<STR_LIT>" , lbry_conf_path ) <EOL> lines = lbry_conf . readlines ( ) <EOL> log . debug ( "<STR_LIT>" , lbry_conf_path , str ( lines ) ) <EOL> return lines <EOL> d . addCallback ( lambda _ : threads . deferToThread ( get_configuration_file ) ) <EOL> def load_configuration_file ( conf ) : <EOL> for line in conf : <EOL> if len ( line . strip ( ) ) and line . strip ( ) [ <NUM_LIT:0> ] != "<STR_LIT:#>" : <EOL> try : <EOL> field_name , field_value = map ( lambda x : x . strip ( ) , line . strip ( ) . split ( "<STR_LIT:=>" , <NUM_LIT:1> ) ) <EOL> field_name = field_name . lower ( ) <EOL> except ValueError : <EOL> raise ValueError ( "<STR_LIT>" % line ) <EOL> if field_name == "<STR_LIT>" : <EOL> known_nodes = [ ] <EOL> nodes = field_value . split ( "<STR_LIT:U+002C>" ) <EOL> for n in nodes : <EOL> if n . strip ( ) : <EOL> try : <EOL> ip_address , port_string = map ( lambda x : x . strip ( ) , n . split ( "<STR_LIT::>" ) ) <EOL> ip_numbers = ip_address . split ( "<STR_LIT:.>" ) <EOL> assert len ( ip_numbers ) == <NUM_LIT:4> <EOL> for ip_num in ip_numbers : <EOL> num = int ( ip_num ) <EOL> assert <NUM_LIT:0> <= num <= <NUM_LIT:255> <EOL> known_nodes . append ( ( ip_address , int ( port_string ) ) ) <EOL> except ( ValueError , AssertionError ) : <EOL> raise ValueError ( "<STR_LIT>" % str ( field_value ) ) <EOL> log . debug ( "<STR_LIT>" , str ( known_nodes ) ) <EOL> self . known_dht_nodes = known_nodes <EOL> elif field_name == "<STR_LIT>" : <EOL> if field_value . lower ( ) == "<STR_LIT:true>" : <EOL> run_server = True <EOL> elif field_value . lower ( ) == "<STR_LIT:false>" : <EOL> run_server = False <EOL> else : <EOL> raise ValueError ( "<STR_LIT>" % field_value ) <EOL> log . debug ( "<STR_LIT>" , str ( run_server ) ) <EOL> self . run_server = run_server <EOL> elif field_name == "<STR_LIT>" : <EOL> log . debug ( "<STR_LIT>" , str ( field_value ) ) <EOL> self . db_dir = field_value <EOL> self . blobfile_dir = os . path . join ( self . db_dir , "<STR_LIT>" ) <EOL> elif field_name == "<STR_LIT>" : <EOL> log . debug ( "<STR_LIT>" , str ( field_value ) ) <EOL> self . wallet_dir = field_value <EOL> elif field_name == "<STR_LIT>" : <EOL> log . debug ( "<STR_LIT>" , str ( field_value ) ) <EOL> self . wallet_conf = field_value <EOL> elif field_name == "<STR_LIT>" : <EOL> try : <EOL> peer_port = int ( field_value ) <EOL> assert <NUM_LIT:0> <= peer_port <= <NUM_LIT> <EOL> log . debug ( "<STR_LIT>" , str ( peer_port ) ) <EOL> self . peer_port = peer_port <EOL> except ( ValueError , AssertionError ) : <EOL> raise ValueError ( "<STR_LIT>" % field_value ) <EOL> elif field_name == "<STR_LIT>" : <EOL> try : <EOL> dht_port = int ( field_value ) <EOL> assert <NUM_LIT:0> <= dht_port <= <NUM_LIT> <EOL> log . debug ( "<STR_LIT>" , str ( dht_port ) ) <EOL> self . dht_node_port = dht_port <EOL> except ( ValueError , AssertionError ) : <EOL> raise ValueError ( "<STR_LIT>" % field_value ) <EOL> elif field_name == "<STR_LIT>" : <EOL> if field_value . lower ( ) == "<STR_LIT:true>" : <EOL> use_upnp = True <EOL> elif field_value . lower ( ) == "<STR_LIT:false>" : <EOL> use_upnp = False <EOL> else : <EOL> raise ValueError ( "<STR_LIT>" % str ( field_value ) ) <EOL> log . debug ( "<STR_LIT>" , str ( use_upnp ) ) <EOL> self . use_upnp = use_upnp <EOL> elif field_name == "<STR_LIT>" : <EOL> try : <EOL> rate = float ( field_value ) <EOL> assert rate >= <NUM_LIT:0.0> <EOL> log . debug ( "<STR_LIT>" , str ( rate ) ) <EOL> self . default_blob_data_payment_rate = rate <EOL> except ( ValueError , AssertionError ) : <EOL> raise ValueError ( "<STR_LIT>" % str ( field_value ) ) <EOL> elif field_name == "<STR_LIT>" : <EOL> if field_value . lower ( ) == "<STR_LIT:true>" : <EOL> start_lbrycrdd = True <EOL> elif field_value . lower ( ) == "<STR_LIT:false>" : <EOL> start_lbrycrdd = False <EOL> else : <EOL> raise ValueError ( "<STR_LIT>" % field_value ) <EOL> log . debug ( "<STR_LIT>" , str ( start_lbrycrdd ) ) <EOL> self . start_lbrycrdd = start_lbrycrdd <EOL> elif field_name == "<STR_LIT>" : <EOL> self . lbrycrdd_path = field_value <EOL> elif field_name == "<STR_LIT>" : <EOL> log . debug ( "<STR_LIT>" , str ( field_value ) ) <EOL> self . download_directory = field_value <EOL> elif field_name == "<STR_LIT>" : <EOL> if field_value . lower ( ) == "<STR_LIT:true>" : <EOL> self . delete_blobs_on_remove = True <EOL> elif field_value . lower ( ) == "<STR_LIT:false>" : <EOL> self . delete_blobs_on_remove = False <EOL> else : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> else : <EOL> log . warning ( "<STR_LIT>" , field_name ) <EOL> d . addCallback ( load_configuration_file ) <EOL> return d <EOL> def _create_directory ( self ) : <EOL> if not os . path . exists ( self . db_dir ) : <EOL> os . makedirs ( self . db_dir ) <EOL> db_revision = open ( os . path . join ( self . db_dir , "<STR_LIT>" ) , mode = '<STR_LIT:w>' ) <EOL> db_revision . write ( str ( self . current_db_revision ) ) <EOL> db_revision . close ( ) <EOL> log . debug ( "<STR_LIT>" , str ( self . db_dir ) ) <EOL> if not os . path . exists ( self . blobfile_dir ) : <EOL> os . makedirs ( self . blobfile_dir ) <EOL> log . debug ( "<STR_LIT>" , str ( self . blobfile_dir ) ) <EOL> if os . name == "<STR_LIT>" : <EOL> if not os . path . exists ( self . wallet_dir ) : <EOL> os . makedirs ( self . wallet_dir ) <EOL> if not os . path . exists ( self . wallet_conf ) : <EOL> lbrycrd_conf = open ( self . wallet_conf , mode = '<STR_LIT:w>' ) <EOL> self . wallet_user = "<STR_LIT>" <EOL> lbrycrd_conf . write ( "<STR_LIT>" % self . wallet_user ) <EOL> self . wallet_password = binascii . hexlify ( Random . new ( ) . read ( <NUM_LIT:20> ) ) <EOL> lbrycrd_conf . write ( "<STR_LIT>" % self . wallet_password ) <EOL> lbrycrd_conf . write ( "<STR_LIT>" ) <EOL> lbrycrd_conf . close ( ) <EOL> else : <EOL> lbrycrd_conf = open ( self . wallet_conf ) <EOL> for l in lbrycrd_conf : <EOL> if l . startswith ( "<STR_LIT>" ) : <EOL> self . wallet_user = l [ <NUM_LIT:8> : ] . rstrip ( '<STR_LIT:\n>' ) <EOL> if l . startswith ( "<STR_LIT>" ) : <EOL> self . wallet_password = l [ <NUM_LIT:12> : ] . rstrip ( '<STR_LIT:\n>' ) <EOL> if l . startswith ( "<STR_LIT>" ) : <EOL> self . wallet_rpc_port = int ( l [ <NUM_LIT:8> : - <NUM_LIT:1> ] . rstrip ( '<STR_LIT:\n>' ) ) <EOL> def _get_session ( self ) : <EOL> lbrycrdd_path = None <EOL> if self . start_lbrycrdd is True : <EOL> lbrycrdd_path = self . lbrycrdd_path <EOL> if not lbrycrdd_path : <EOL> lbrycrdd_path = self . default_lbrycrdd_path <EOL> if sys . platform == '<STR_LIT>' : <EOL> os . chdir ( "<STR_LIT>" ) <EOL> wallet = LBRYcrdWallet ( self . db_dir , wallet_dir = self . wallet_dir , wallet_conf = self . wallet_conf , <EOL> lbrycrdd_path = lbrycrdd_path ) <EOL> peer_port = None <EOL> if self . run_server : <EOL> peer_port = self . peer_port <EOL> self . session = LBRYSession ( self . default_blob_data_payment_rate , db_dir = self . db_dir , <EOL> blob_dir = self . blobfile_dir , use_upnp = self . use_upnp , wallet = wallet , <EOL> known_dht_nodes = self . known_dht_nodes , dht_node_port = self . dht_node_port , <EOL> peer_port = peer_port ) <EOL> return self . session . setup ( ) <EOL> def _setup_stream_info_manager ( self ) : <EOL> self . stream_info_manager = TempLBRYFileMetadataManager ( ) <EOL> return defer . succeed ( True ) <EOL> def start_server ( self ) : <EOL> if self . run_server : <EOL> self . blob_request_payment_rate_manager = PaymentRateManager ( <EOL> self . session . base_payment_rate_manager , <EOL> self . default_blob_data_payment_rate <EOL> ) <EOL> handlers = [ <EOL> BlobAvailabilityHandlerFactory ( self . session . blob_manager ) , <EOL> self . session . wallet . get_wallet_info_query_handler_factory ( ) , <EOL> BlobRequestHandlerFactory ( self . session . blob_manager , self . session . wallet , <EOL> self . blob_request_payment_rate_manager ) <EOL> ] <EOL> server_factory = ServerProtocolFactory ( self . session . rate_limiter , <EOL> handlers , <EOL> self . session . peer_manager ) <EOL> from twisted . internet import reactor <EOL> self . lbry_server_port = reactor . listenTCP ( self . peer_port , server_factory ) <EOL> return defer . succeed ( True ) <EOL> def stop_server ( self ) : <EOL> if self . lbry_server_port is not None : <EOL> self . lbry_server_port , p = None , self . lbry_server_port <EOL> return defer . maybeDeferred ( p . stopListening ) <EOL> else : <EOL> return defer . succeed ( True ) <EOL> def _setup_stream_identifier ( self ) : <EOL> add_lbry_file_to_sd_identifier ( self . sd_identifier ) <EOL> file_saver_factory = LBRYFileSaverFactory ( self . session . peer_finder , self . session . rate_limiter , <EOL> self . session . blob_manager , self . stream_info_manager , <EOL> self . session . wallet , self . download_directory ) <EOL> self . sd_identifier . add_stream_downloader_factory ( LBRYFileStreamType , file_saver_factory ) <EOL> file_opener_factory = LBRYFileOpenerFactory ( self . session . peer_finder , self . session . rate_limiter , <EOL> self . session . blob_manager , self . stream_info_manager , <EOL> self . session . wallet ) <EOL> self . sd_identifier . add_stream_downloader_factory ( LBRYFileStreamType , file_opener_factory ) <EOL> def check_first_run ( self ) : <EOL> d = self . session . wallet . is_first_run ( ) <EOL> d . addCallback ( lambda is_first_run : self . _do_first_run ( ) if is_first_run else <NUM_LIT:0.0> ) <EOL> return d <EOL> def _do_first_run ( self ) : <EOL> d = self . session . wallet . get_new_address ( ) <EOL> def send_request ( url , data ) : <EOL> r = requests . post ( url , json = data ) <EOL> if r . status_code == <NUM_LIT:200> : <EOL> return r . json ( ) [ '<STR_LIT>' ] <EOL> return <NUM_LIT:0.0> <EOL> def log_error ( err ) : <EOL> log . warning ( "<STR_LIT>" , err . getErrorMessage ( ) ) <EOL> return <NUM_LIT:0.0> <EOL> def request_credits ( address ) : <EOL> url = "<STR_LIT>" <EOL> data = { "<STR_LIT:address>" : address } <EOL> d = threads . deferToThread ( send_request , url , data ) <EOL> d . addErrback ( log_error ) <EOL> return d <EOL> d . addCallback ( request_credits ) <EOL> return d <EOL> def _resolve_name ( self , uri ) : <EOL> return self . session . wallet . get_stream_info_for_name ( uri ) <EOL> def download_stream ( self , stream_frame , uri ) : <EOL> resolve_d = self . _resolve_name ( uri ) <EOL> stream_frame . show_metadata_status ( "<STR_LIT>" ) <EOL> stream_frame . cancel_func = resolve_d . cancel <EOL> payment_rate_manager = PaymentRateManager ( self . session . base_payment_rate_manager ) <EOL> def update_stream_name ( value ) : <EOL> if '<STR_LIT:name>' in value : <EOL> stream_frame . show_name ( value [ '<STR_LIT:name>' ] ) <EOL> if '<STR_LIT:description>' in value : <EOL> stream_frame . show_description ( value [ '<STR_LIT:description>' ] ) <EOL> if '<STR_LIT>' in value : <EOL> stream_frame . show_thumbnail ( value [ '<STR_LIT>' ] ) <EOL> return value <EOL> def get_sd_hash ( value ) : <EOL> if '<STR_LIT>' in value : <EOL> return value [ '<STR_LIT>' ] <EOL> raise UnknownNameError ( uri ) <EOL> def get_sd_blob ( sd_hash ) : <EOL> stream_frame . show_metadata_status ( "<STR_LIT>" ) <EOL> get_sd_d = StreamDescriptor . download_sd_blob ( self . session , sd_hash , <EOL> payment_rate_manager ) <EOL> get_sd_d . addCallback ( self . sd_identifier . get_metadata_for_sd_blob ) <EOL> get_sd_d . addCallbacks ( choose_download_factory , bad_sd_blob ) <EOL> return get_sd_d <EOL> def get_info_from_validator ( info_validator ) : <EOL> stream_name = None <EOL> stream_size = None <EOL> for field , val in info_validator . info_to_show ( ) : <EOL> if field == "<STR_LIT>" : <EOL> stream_name = val <EOL> elif field == "<STR_LIT>" and stream_name is None : <EOL> stream_name = val <EOL> elif field == "<STR_LIT>" : <EOL> stream_size = int ( val ) <EOL> if stream_size is None : <EOL> stream_size = "<STR_LIT>" <EOL> if stream_name is None : <EOL> stream_name = "<STR_LIT>" <EOL> return stream_name , stream_size <EOL> def choose_download_factory ( metadata ) : <EOL> stream_name , stream_size = get_info_from_validator ( metadata . validator ) <EOL> if isinstance ( stream_size , ( int , long ) ) : <EOL> price = payment_rate_manager . get_effective_min_blob_data_payment_rate ( ) <EOL> estimated_cost = stream_size * <NUM_LIT:1.0> / <NUM_LIT:2> ** <NUM_LIT:20> * price <EOL> else : <EOL> estimated_cost = "<STR_LIT>" <EOL> stream_frame . show_stream_metadata ( stream_name , stream_size , estimated_cost ) <EOL> available_options = metadata . options . get_downloader_options ( metadata . validator , <EOL> payment_rate_manager ) <EOL> stream_frame . show_download_options ( available_options ) <EOL> get_downloader_d = defer . Deferred ( ) <EOL> def create_downloader ( f , chosen_options ) : <EOL> def fire_get_downloader_d ( downloader ) : <EOL> if not get_downloader_d . called : <EOL> get_downloader_d . callback ( downloader ) <EOL> stream_frame . disable_download_buttons ( ) <EOL> d = f . make_downloader ( metadata , chosen_options , <EOL> payment_rate_manager ) <EOL> d . addCallback ( fire_get_downloader_d ) <EOL> for factory in metadata . factories : <EOL> def choose_factory ( f = factory ) : <EOL> chosen_options = stream_frame . get_chosen_options ( ) <EOL> create_downloader ( f , chosen_options ) <EOL> stream_frame . add_download_factory ( factory , choose_factory ) <EOL> get_downloader_d . addCallback ( start_download ) <EOL> return get_downloader_d <EOL> def show_stream_status ( downloader ) : <EOL> total_bytes = downloader . get_total_bytes_cached ( ) <EOL> bytes_left_to_download = downloader . get_bytes_left_to_download ( ) <EOL> points_paid = payment_rate_manager . points_paid <EOL> payment_rate = payment_rate_manager . get_effective_min_blob_data_payment_rate ( ) <EOL> points_remaining = <NUM_LIT:1.0> * bytes_left_to_download * payment_rate / <NUM_LIT:2> ** <NUM_LIT:20> <EOL> stream_frame . show_progress ( total_bytes , bytes_left_to_download , <EOL> points_paid , points_remaining ) <EOL> def show_finished ( arg , downloader ) : <EOL> show_stream_status ( downloader ) <EOL> stream_frame . show_download_done ( payment_rate_manager . points_paid ) <EOL> return arg <EOL> def start_download ( downloader ) : <EOL> stream_frame . stream_hash = downloader . stream_hash <EOL> l = task . LoopingCall ( show_stream_status , downloader ) <EOL> l . start ( <NUM_LIT:1> ) <EOL> d = downloader . start ( ) <EOL> stream_frame . cancel_func = downloader . stop <EOL> def stop_looping_call ( arg ) : <EOL> l . stop ( ) <EOL> stream_frame . cancel_func = resolve_d . cancel <EOL> return arg <EOL> d . addBoth ( stop_looping_call ) <EOL> d . addCallback ( show_finished , downloader ) <EOL> return d <EOL> def lookup_failed ( err ) : <EOL> stream_frame . show_metadata_status ( "<STR_LIT>" ) <EOL> return err <EOL> def bad_sd_blob ( err ) : <EOL> stream_frame . show_metadata_status ( "<STR_LIT>" ) <EOL> return err <EOL> resolve_d . addCallback ( update_stream_name ) <EOL> resolve_d . addCallback ( get_sd_hash ) <EOL> resolve_d . addCallbacks ( get_sd_blob , lookup_failed ) <EOL> def show_err ( err ) : <EOL> tkMessageBox . showerror ( title = "<STR_LIT>" , message = err . getErrorMessage ( ) ) <EOL> log . error ( err . getErrorMessage ( ) ) <EOL> stream_frame . show_download_done ( payment_rate_manager . points_paid ) <EOL> resolve_d . addErrback ( lambda err : err . trap ( defer . CancelledError , UnknownNameError , <EOL> UnknownStreamTypeError , InvalidStreamDescriptorError , <EOL> InvalidStreamInfoError ) ) <EOL> resolve_d . addErrback ( show_err ) <EOL> def delete_associated_blobs ( ) : <EOL> if stream_frame . stream_hash is None or self . delete_blobs_on_remove is False : <EOL> return defer . succeed ( True ) <EOL> d1 = self . stream_info_manager . get_blobs_for_stream ( stream_frame . stream_hash ) <EOL> def get_blob_hashes ( blob_infos ) : <EOL> return [ b [ <NUM_LIT:0> ] for b in blob_infos if b [ <NUM_LIT:0> ] is not None ] <EOL> d1 . addCallback ( get_blob_hashes ) <EOL> d2 = self . stream_info_manager . get_sd_blob_hashes_for_stream ( stream_frame . stream_hash ) <EOL> def combine_blob_hashes ( results ) : <EOL> blob_hashes = [ ] <EOL> for success , result in results : <EOL> if success is True : <EOL> blob_hashes . extend ( result ) <EOL> return blob_hashes <EOL> def delete_blobs ( blob_hashes ) : <EOL> return self . session . blob_manager . delete_blobs ( blob_hashes ) <EOL> dl = defer . DeferredList ( [ d1 , d2 ] , fireOnOneErrback = True ) <EOL> dl . addCallback ( combine_blob_hashes ) <EOL> dl . addCallback ( delete_blobs ) <EOL> return dl <EOL> resolve_d . addCallback ( lambda _ : delete_associated_blobs ( ) ) <EOL> self . _add_download_deferred ( resolve_d , stream_frame ) <EOL> def _add_download_deferred ( self , d , stream_frame ) : <EOL> self . download_deferreds . append ( d ) <EOL> self . stream_frames . append ( stream_frame ) <EOL> def remove_from_list ( ) : <EOL> self . download_deferreds . remove ( d ) <EOL> self . stream_frames . remove ( stream_frame ) <EOL> d . addBoth ( lambda _ : remove_from_list ( ) ) </s>
