def setup_session_config(self): from Tribler.Core.SessionConfig import SessionStartupConfig config = SessionStartupConfig() config.set_install_dir( os.path.abspath(os.path.join(BASE_DIR, "tribler"))) config.set_state_dir( os.path.abspath( os.path.join(BASE_DIR, "output", ".Tribler-%d") % getpid())) config.set_torrent_checking(False) config.set_multicast_local_peer_discovery(False) config.set_megacache(False) config.set_dispersy(True) config.set_mainline_dht(False) config.set_torrent_collecting(False) config.set_libtorrent(False) config.set_dht_torrent_collecting(False) config.set_enable_torrent_search(False) config.set_enable_channel_search(False) config.set_videoserver_enabled(False) config.set_http_api_enabled(False) config.set_upgrader_enabled(False) config.set_listen_port(20000 + self.scenario_runner._peernumber) if self.dispersy_port is None: self.dispersy_port = 21000 + self.scenario_runner._peernumber config.set_dispersy_port(self.dispersy_port) logging.error("Dispersy port set to %d" % self.dispersy_port) return config
def initialize(self): sscfg = SessionStartupConfig() if self._opt.statedir: sscfg.set_state_dir(unicode(os.path.realpath(self._opt.statedir))) if self._opt.port: sscfg.set_dispersy_port(self._opt.port) if self._opt.nickname: sscfg.set_nickname(self._opt.nickname) # pass rss config if not self._opt.rss_config: self._logger.error(u"rss_config unspecified") self.rss_list = parge_rss_config_file(self._opt.rss_config) sscfg.set_megacache(True) sscfg.set_torrent_collecting(True) sscfg.set_torrent_checking(True) sscfg.set_enable_torrent_search(True) sscfg.set_enable_channel_search(True) self._logger.info(u"Starting session...") self.session = Session(sscfg) self.session.prestart() # add dispersy start callbacks self.session.add_observer(self.dispersy_started, NTFY_DISPERSY, [NTFY_STARTED]) self.session.start()
class TriblerSession(BaseManager): _sconfig = None _dispersy = None _running = False def _connect(self): """ Copies the libswift and ffmpeg binaries when on Android. :return: """ if not self._connected: self._connected = True # Copy the swift and ffmpeg binaries if is_android(strict=True): binaries = ['swift', 'ffmpeg'] for binary in binaries: _logger.info("Setting up the %s binary.." % binary) if not self._copy_binary(binary): _logger.error("Unable to find or copy the %s binary!" % binary) else: raise RuntimeError('TriblerSession already connected') def _xmlrpc_register(self, xmlrpc): """ Register the public functions in this manager with an XML-RPC Manager. :param xmlrpc: The XML-RPC Manager it should register to. :return: Nothing. """ xmlrpc.register_function(self.start_session, "tribler.start_session") xmlrpc.register_function(self.stop_session, "tribler.stop_session") def _copy_binary(self, binary_name): """ Copy a binary, such as swift, from the sdcard (which is mounted with noexec) to the ANDROID_PRIVATE folder which does allow it. If the binary already exists, do nothing. :param binary_name: The name of the binary that should be copied. :return: Boolean indicating success. """ # We are on android, setup the swift binary! sdcard_path = os.getcwd() binary_source = os.path.join(sdcard_path, binary_name) binary_dest = os.path.join(os.environ['ANDROID_PRIVATE'], binary_name) if not os.path.exists(binary_dest): if not os.path.exists(binary_source): _logger.error( "Looked at %s and %s, but couldn't find a '%s' binary!" % (binary_source, binary_dest, binary_name)) return False _logger.warn("Copy '%s' binary (%s -> %s)" % (binary_name, binary_source, binary_dest)) shutil.copy2(binary_source, binary_dest) # TODO: Set a more conservative permission os.chmod(binary_dest, 0777) return True def get_session(self): """ Get the current Tribler session. :return: Tribler session, or None if no session is started yet. """ return self._session def start_session(self): """ This function loads any previous configuration files from the TRIBLER_STATE_DIR environment variable and then starts a Tribler session. :return: Nothing. """ if self._running: return False _logger.info("Set tribler_state_dir to %s" % os.environ['TRIBLER_STATE_DIR']) # Load configuration file (if exists) cfgfilename = Session.get_default_config_filename( os.environ['TRIBLER_STATE_DIR']) try: self._sconfig = SessionStartupConfig.load(cfgfilename) _logger.info("Loaded previous configuration file from %s" % cfgfilename) except: self._sconfig = SessionStartupConfig() self._sconfig.set_state_dir(os.environ['TRIBLER_STATE_DIR']) _logger.info( "No previous configuration file found, creating one in %s" % os.environ['TRIBLER_STATE_DIR']) # Set torrent collecting directory: dlcfgfilename = get_default_dscfg_filename( self._sconfig.get_state_dir()) _logger.debug("main: Download config %s", dlcfgfilename) try: defaultDLConfig = DefaultDownloadStartupConfig.load(dlcfgfilename) except: defaultDLConfig = DefaultDownloadStartupConfig.getInstance() if not defaultDLConfig.get_dest_dir(): defaultDLConfig.set_dest_dir(os.environ['TRIBLER_DOWNLOAD_DIR']) self._sconfig.set_torrent_collecting_dir( os.path.join(os.environ['TRIBLER_DOWNLOAD_DIR'])) # Create download directory: if not os.path.isdir(defaultDLConfig.get_dest_dir()): try: _logger.info("Creating download directory: %s" % defaultDLConfig.get_dest_dir()) os.makedirs(defaultDLConfig.get_dest_dir()) except: _logger.error("Couldn't create download directory! (%s)" % defaultDLConfig.get_dest_dir()) # TODO: This is temporary for testing: from jnius import autoclass python_activity = autoclass('org.renpy.android.PythonActivity') files_dir = python_activity.mActivity.getFilesDir().getAbsolutePath() install_dir = files_dir + u'/lib/python2.7/site-packages' _logger.info("Set tribler_install_dir to %s" % install_dir) self._sconfig.set_install_dir(install_dir) self._sconfig.set_state_dir(files_dir + '.Tribler') # TODO: ^End of temporary test. # Disable unwanted dependencies: self._sconfig.set_torrent_store(True) self._sconfig.set_torrent_checking(True) self._sconfig.set_multicast_local_peer_discovery(True) self._sconfig.set_mainline_dht(True) self._sconfig.set_dht_torrent_collecting(True) self._sconfig.set_enable_channel_search(False) self._sconfig.set_torrent_collecting_max_torrents(5000) _logger.info("Starting Tribler session..") self._session = Session(self._sconfig) upgrader = self._session.prestart() while not upgrader.is_done: time.sleep(0.1) self._session.start() _logger.info("Tribler session started!") self._dispersy = self._session.get_dispersy_instance() self.define_communities() # Dispersy init communitites callback function @call_on_reactor_thread def define_communities(self): """ Load the dispersy communities. This function must be run on the Twisted reactor thread. :return: Nothing. """ integrate_with_tribler = True comm_args = {'integrate_with_tribler': integrate_with_tribler} from Tribler.community.search.community import SearchCommunity _logger.info("Preparing to load dispersy communities...") comm = self._dispersy.define_auto_load(SearchCommunity, self._session.dispersy_member, load=True, kargs=comm_args) _logger.debug("Currently loaded dispersy communities: %s" % comm) # 17/07/13 Boudewijn: the missing-member message send by the BarterCommunity on the swift port is crashing # 6.1 clients. We will disable the BarterCommunity for version 6.2, giving people some time to upgrade # their version before enabling it again. # if swift_process: # dispersy.define_auto_load(BarterCommunity, # s.dispersy_member, # (swift_process,), # load=True) #comm = self._dispersy.define_auto_load(ChannelCommunity, self._session.dispersy_member, load=True, # kargs=comm_args) #_logger.debug("Currently loaded dispersy communities: %s" % comm) #comm = self._dispersy.define_auto_load(PreviewChannelCommunity, self._session.dispersy_member, kargs=comm_args) #_logger.debug("Currently loaded dispersy communities: %s" % comm) self._running = True def is_running(self): return self._running def stop_session(self): """ Unloads the Tribler session. :return: Nothing. """ _logger.info("Create checkpoint..") self._session.checkpoint() _logger.info("Shutting down Tribler..") self._session.shutdown() # Just a tad of extra time time.sleep(1) self._running = False _logger.info("Bye bye") return True
class ABCApp(object): def __init__(self, params, installdir, autoload_discovery=True, use_torrent_search=True, use_channel_search=True): assert not isInIOThread(), "isInIOThread() seems to not be working correctly" self._logger = logging.getLogger(self.__class__.__name__) self.params = params self.installdir = installdir self.state_dir = None self.error = None self.last_update = 0 self.ready = False self.done = False self.frame = None self.upgrader = None self.said_start_playback = False self.decodeprogress = 0 self.old_reputation = 0 # DISPERSY will be set when available self.dispersy = None # BARTER_COMMUNITY will be set when both Dispersy and the EffortCommunity are available self.barter_community = None self.tunnel_community = None self.torrentfeed = None self.webUI = None self.utility = None # Stage 1 start session = self.InitStage1(installdir, autoload_discovery=autoload_discovery, use_torrent_search=use_torrent_search, use_channel_search=use_channel_search) self.splash = None try: bm = self.gui_image_manager.getImage(u'splash.png') self.splash = GaugeSplash(bm, "Loading...", 13) self.splash.Show() self._logger.info('Client Starting Up.') self._logger.info("Tribler is using %s as working directory", self.installdir) # Stage 2: show the splash window and start the session self.splash.tick('Starting API') s = self.startAPI(session, self.splash.tick) self.utility = Utility(self.installdir, s.get_state_dir()) if self.utility.read_config(u'saveas', u'downloadconfig'): DefaultDownloadStartupConfig.getInstance().set_dest_dir(self.utility.read_config(u'saveas', u'downloadconfig')) self.utility.set_app(self) self.utility.set_session(s) self.guiUtility = GUIUtility.getInstance(self.utility, self.params, self) GUIDBProducer.getInstance() self._logger.info('Tribler Version: %s Build: %s', version_id, commit_id) version_info = self.utility.read_config('version_info') if version_info.get('version_id', None) != version_id: # First run of a different version version_info['first_run'] = int(time()) version_info['version_id'] = version_id self.utility.write_config('version_info', version_info) self.splash.tick('Starting session and upgrading database (it may take a while)') s.start() self.dispersy = s.lm.dispersy self.splash.tick('Loading userdownloadchoice') from Tribler.Main.vwxGUI.UserDownloadChoice import UserDownloadChoice UserDownloadChoice.get_singleton().set_utility(self.utility) self.splash.tick('Initializing Family Filter') cat = Category.getInstance(session) state = self.utility.read_config('family_filter') if state in (1, 0): cat.set_family_filter(state == 1) else: self.utility.write_config('family_filter', 1) self.utility.flush_config() cat.set_family_filter(True) # Create global speed limits self.splash.tick('Setting up speed limits') # Counter to suppress some event from occurring self.ratestatecallbackcount = 0 maxup = self.utility.read_config('maxuploadrate') maxdown = self.utility.read_config('maxdownloadrate') # set speed limits using LibtorrentMgr s.set_max_upload_speed(maxup) s.set_max_download_speed(maxdown) # Only allow updates to come in after we defined ratelimiter self.prevActiveDownloads = [] s.set_download_states_callback(self.sesscb_states_callback) # Schedule task for checkpointing Session, to avoid hash checks after # crashes. startWorker(consumer=None, workerFn=self.guiservthread_checkpoint_timer, delay=SESSION_CHECKPOINT_INTERVAL) if not ALLOW_MULTIPLE: # Put it here so an error is shown in the startup-error popup # Start server for instance2instance communication Instance2InstanceServer(self.utility.read_config('i2ilistenport'), self.i2ithread_readlinecallback) self.splash.tick('GUIUtility register') self.guiUtility.register() self.frame = MainFrame(self, None, PLAYBACKMODE_INTERNAL in return_feasible_playback_modes(), self.splash.tick) self.frame.SetIcon(wx.Icon(os.path.join(self.installdir, 'Tribler', 'Main', 'vwxGUI', 'images', 'tribler.ico'), wx.BITMAP_TYPE_ICO)) # Arno, 2011-06-15: VLC 1.1.10 pops up separate win, don't have two. self.frame.videoframe = None if PLAYBACKMODE_INTERNAL in return_feasible_playback_modes(): vlcwrap = s.lm.videoplayer.get_vlcwrap() wx.CallLater(3000, vlcwrap._init_vlc) self.frame.videoframe = VideoDummyFrame(self.frame.videoparentpanel, self.utility, vlcwrap) if sys.platform == 'win32': wx.CallAfter(self.frame.top_bg.Refresh) wx.CallAfter(self.frame.top_bg.Layout) else: self.frame.top_bg.Layout() # Arno, 2007-05-03: wxWidgets 2.8.3.0 and earlier have the MIME-type for .bmp # files set to 'image/x-bmp' whereas 'image/bmp' is the official one. try: bmphand = None hands = wx.Image.GetHandlers() for hand in hands: # print "Handler",hand.GetExtension(),hand.GetType(),hand.GetMimeType() if hand.GetMimeType() == 'image/x-bmp': bmphand = hand break # wx.Image.AddHandler() if bmphand is not None: bmphand.SetMimeType('image/bmp') except: # wx < 2.7 don't like wx.Image.GetHandlers() print_exc() self.splash.Destroy() self.frame.Show(True) session.lm.threadpool.call_in_thread(0, self.guiservthread_free_space_check) self.torrentfeed = RssParser.getInstance() self.webUI = None if self.utility.read_config('use_webui'): try: from Tribler.Main.webUI.webUI import WebUI self.webUI = WebUI.getInstance(self.guiUtility.library_manager, self.guiUtility.torrentsearch_manager, self.utility.read_config('webui_port')) self.webUI.start() except Exception: print_exc() self.emercoin_mgr = None try: from Tribler.Main.Emercoin.EmercoinMgr import EmercoinMgr self.emercoin_mgr = EmercoinMgr(self.utility) except Exception: print_exc() wx.CallAfter(self.PostInit2) # 08/02/10 Boudewijn: Working from home though console # doesn't allow me to press close. The statement below # gracefully closes Tribler after 120 seconds. # wx.CallLater(120*1000, wx.GetApp().Exit) self.ready = True except Exception as e: if self.splash: self.splash.Destroy() self.onError(e) def InitStage1(self, installdir, autoload_discovery=True, use_torrent_search=True, use_channel_search=True): """ Stage 1 start: pre-start the session to handle upgrade. """ # Make sure the installation dir is on the PATH os.environ['PATH'] += os.pathsep + os.path.abspath(installdir) self.gui_image_manager = GuiImageManager.getInstance(installdir) # Start Tribler Session defaultConfig = SessionStartupConfig() state_dir = defaultConfig.get_state_dir() # Switch to the state dir so relative paths can be used (IE, in LevelDB store paths) if not os.path.exists(state_dir): os.makedirs(state_dir) os.chdir(state_dir) cfgfilename = Session.get_default_config_filename(state_dir) self._logger.debug(u"Session config %s", cfgfilename) try: self.sconfig = SessionStartupConfig.load(cfgfilename) except: try: self.sconfig = convertSessionConfig(os.path.join(state_dir, 'sessconfig.pickle'), cfgfilename) convertMainConfig(state_dir, os.path.join(state_dir, 'abc.conf'), os.path.join(state_dir, STATEDIR_GUICONFIG)) except: self.sconfig = SessionStartupConfig() self.sconfig.set_state_dir(state_dir) self.sconfig.set_install_dir(self.installdir) # TODO(emilon): Do we still want to force limit this? With the new # torrent store it should be pretty fast even with more that that. # Arno, 2010-03-31: Hard upgrade to 50000 torrents collected self.sconfig.set_torrent_collecting_max_torrents(50000) dlcfgfilename = get_default_dscfg_filename(self.sconfig.get_state_dir()) self._logger.debug("main: Download config %s", dlcfgfilename) try: defaultDLConfig = DefaultDownloadStartupConfig.load(dlcfgfilename) except: try: defaultDLConfig = convertDefaultDownloadConfig( os.path.join(state_dir, 'dlconfig.pickle'), dlcfgfilename) except: defaultDLConfig = DefaultDownloadStartupConfig.getInstance() if not defaultDLConfig.get_dest_dir(): defaultDLConfig.set_dest_dir(get_default_dest_dir()) if not os.path.isdir(defaultDLConfig.get_dest_dir()): try: os.makedirs(defaultDLConfig.get_dest_dir()) except: # Could not create directory, ask user to select a different location dlg = wx.DirDialog(None, "Could not find download directory, please select a new location to store your downloads", style=wx.DEFAULT_DIALOG_STYLE) dlg.SetPath(get_default_dest_dir()) if dlg.ShowModal() == wx.ID_OK: new_dest_dir = dlg.GetPath() defaultDLConfig.set_dest_dir(new_dest_dir) defaultDLConfig.save(dlcfgfilename) self.sconfig.save(cfgfilename) else: # Quit self.onError = lambda e: self._logger.error( "tribler: quitting due to non-existing destination directory") raise Exception() if not use_torrent_search: self.sconfig.set_enable_torrent_search(False) if not use_channel_search: self.sconfig.set_enable_channel_search(False) session = Session(self.sconfig, autoload_discovery=autoload_discovery) session.add_observer(self.show_upgrade_dialog, NTFY_UPGRADER, [NTFY_STARTED]) self.upgrader = session.prestart() while not self.upgrader.is_done: wx.SafeYield() sleep(0.1) return session @forceWxThread def show_upgrade_dialog(self, subject, changetype, objectID, *args): assert wx.Thread_IsMain() upgrade_dialog = TriblerUpgradeDialog(self.gui_image_manager, self.upgrader) failed = upgrade_dialog.ShowModal() upgrade_dialog.Destroy() if failed: wx.MessageDialog(None, "Failed to upgrade the on disk data.\n\n" "Tribler has backed up the old data and will now start from scratch.\n\n" "Get in contact with the Tribler team if you want to help debugging this issue.\n\n" "Error was: %s" % self.upgrader.current_status, "Data format upgrade failed", wx.OK | wx.CENTRE | wx.ICON_EXCLAMATION).ShowModal() def _frame_and_ready(self): return self.ready and self.frame and self.frame.ready def PostInit2(self): self.frame.Raise() self.startWithRightView() self.set_reputation() s = self.utility.session s.add_observer(self.sesscb_ntfy_reachable, NTFY_REACHABLE, [NTFY_INSERT]) s.add_observer(self.sesscb_ntfy_activities, NTFY_ACTIVITIES, [NTFY_INSERT], cache=10) s.add_observer(self.sesscb_ntfy_channelupdates, NTFY_CHANNELCAST, [NTFY_INSERT, NTFY_UPDATE, NTFY_CREATE, NTFY_STATE, NTFY_MODIFIED], cache=10) s.add_observer(self.sesscb_ntfy_channelupdates, NTFY_VOTECAST, [NTFY_UPDATE], cache=10) s.add_observer(self.sesscb_ntfy_myprefupdates, NTFY_MYPREFERENCES, [NTFY_INSERT, NTFY_UPDATE, NTFY_DELETE]) s.add_observer(self.sesscb_ntfy_torrentupdates, NTFY_TORRENTS, [NTFY_UPDATE, NTFY_INSERT], cache=10) s.add_observer(self.sesscb_ntfy_playlistupdates, NTFY_PLAYLISTS, [NTFY_INSERT, NTFY_UPDATE]) s.add_observer(self.sesscb_ntfy_commentupdates, NTFY_COMMENTS, [NTFY_INSERT, NTFY_DELETE]) s.add_observer(self.sesscb_ntfy_modificationupdates, NTFY_MODIFICATIONS, [NTFY_INSERT]) s.add_observer(self.sesscb_ntfy_moderationupdats, NTFY_MODERATIONS, [NTFY_INSERT]) s.add_observer(self.sesscb_ntfy_markingupdates, NTFY_MARKINGS, [NTFY_INSERT]) s.add_observer(self.sesscb_ntfy_torrentfinished, NTFY_TORRENTS, [NTFY_FINISHED]) s.add_observer(self.sesscb_ntfy_magnet, NTFY_TORRENTS, [NTFY_MAGNET_GOT_PEERS, NTFY_MAGNET_STARTED, NTFY_MAGNET_CLOSE]) # TODO(emilon): Use the LogObserver I already implemented # self.dispersy.callback.attach_exception_handler(self.frame.exceptionHandler) startWorker(None, self.loadSessionCheckpoint, delay=5.0, workerType="ThreadPool") # initialize the torrent feed thread channelcast = s.open_dbhandler(NTFY_CHANNELCAST) def db_thread(): return channelcast.getMyChannelId() def wx_thread(delayedResult): my_channel = delayedResult.get() if my_channel: self.torrentfeed.register(self.utility.session, my_channel) self.torrentfeed.addCallback(my_channel, self.guiUtility.channelsearch_manager.createTorrentFromDef) startWorker(wx_thread, db_thread, delay=5.0) def startAPI(self, session, progress): @call_on_reactor_thread def define_communities(*args): assert isInIOThread() from Tribler.community.channel.community import ChannelCommunity from Tribler.community.channel.preview import PreviewChannelCommunity from Tribler.community.tunnel.tunnel_community import TunnelSettings from Tribler.community.tunnel.hidden_community import HiddenTunnelCommunity # make sure this is only called once session.remove_observer(define_communities) dispersy = session.get_dispersy_instance() self._logger.info("tribler: Preparing communities...") now = time() dispersy.attach_progress_handler(self.progressHandler) default_kwargs = {'tribler_session': session} # must be called on the Dispersy thread if session.get_barter_community_enabled(): from Tribler.community.bartercast4.community import BarterCommunity dispersy.define_auto_load(BarterCommunity, session.dispersy_member, load=True) # load metadata community dispersy.define_auto_load(ChannelCommunity, session.dispersy_member, load=True, kargs=default_kwargs) dispersy.define_auto_load(PreviewChannelCommunity, session.dispersy_member, kargs=default_kwargs) keypair = dispersy.crypto.generate_key(u"curve25519") dispersy_member = dispersy.get_member(private_key=dispersy.crypto.key_to_bin(keypair),) settings = TunnelSettings(session.get_install_dir(), tribler_session=session) tunnel_kwargs = {'tribler_session': session, 'settings': settings} self.tunnel_community = dispersy.define_auto_load(HiddenTunnelCommunity, dispersy_member, load=True, kargs=tunnel_kwargs)[0] session.set_anon_proxy_settings(2, ("127.0.0.1", session.get_tunnel_community_socks5_listen_ports())) diff = time() - now self._logger.info("tribler: communities are ready in %.2f seconds", diff) session.add_observer(define_communities, NTFY_DISPERSY, [NTFY_STARTED]) return session @forceWxThread def sesscb_ntfy_myprefupdates(self, subject, changeType, objectID, *args): if self._frame_and_ready(): if changeType in [NTFY_INSERT, NTFY_UPDATE]: if changeType == NTFY_INSERT: if self.frame.searchlist: manager = self.frame.searchlist.GetManager() manager.downloadStarted(objectID) manager = self.frame.selectedchannellist.GetManager() manager.downloadStarted(objectID) manager = self.frame.librarylist.GetManager() manager.downloadStarted(objectID) elif changeType == NTFY_DELETE: self.guiUtility.frame.librarylist.RemoveItem(objectID) if self.guiUtility.frame.librarylist.IsShownOnScreen() and \ self.guiUtility.frame.librarydetailspanel.torrent and \ self.guiUtility.frame.librarydetailspanel.torrent.infohash == objectID: self.guiUtility.frame.librarylist.ResetBottomWindow() self.guiUtility.frame.top_bg.ClearButtonHandlers() if self.guiUtility.frame.librarylist.list.IsEmpty(): self.guiUtility.frame.librarylist.SetData([]) def progressHandler(self, title, message, maximum): from Tribler.Main.Dialogs.ThreadSafeProgressDialog import ThreadSafeProgressDialog return ThreadSafeProgressDialog(title, message, maximum, None, wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME | wx.PD_ESTIMATED_TIME | wx.PD_REMAINING_TIME | wx.PD_AUTO_HIDE) def set_reputation(self): def do_db(): nr_connections = 0 nr_channel_connections = 0 if self.dispersy: for community in self.dispersy.get_communities(): from Tribler.community.search.community import SearchCommunity from Tribler.community.allchannel.community import AllChannelCommunity if isinstance(community, SearchCommunity): nr_connections = community.get_nr_connections() elif isinstance(community, AllChannelCommunity): nr_channel_connections = community.get_nr_connections() return nr_connections, nr_channel_connections def do_wx(delayedResult): if not self.frame: return nr_connections, nr_channel_connections = delayedResult.get() # self.frame.SRstatusbar.set_reputation(myRep, total_down, total_up) # bitmap is 16px wide, -> but first and last pixel do not add anything. percentage = min(1.0, (nr_connections + 1) / 16.0) self.frame.SRstatusbar.SetConnections(percentage, nr_connections, nr_channel_connections) """ set the reputation in the GUI""" if self._frame_and_ready(): startWorker(do_wx, do_db, uId=u"tribler.set_reputation") startWorker(None, self.set_reputation, delay=5.0, workerType="ThreadPool") def sesscb_states_callback(self, dslist): if not self.ready: return 5.0, [] wantpeers = [] self.ratestatecallbackcount += 1 try: # Print stats on Console if self.ratestatecallbackcount % 5 == 0: for ds in dslist: safename = repr(ds.get_download().get_def().get_name()) self._logger.debug( "%s %s %.1f%% dl %.1f ul %.1f n %d", safename, dlstatus_strings[ds.get_status()], 100.0 * ds.get_progress(), ds.get_current_speed(DOWNLOAD), ds.get_current_speed(UPLOAD), ds.get_num_peers()) if ds.get_status() == DLSTATUS_STOPPED_ON_ERROR: self._logger.error("main: Error: %s", repr(ds.get_error())) download = self.utility.session.lm.downloads.get(ds.get_infohash()) if download: download.stop() # show error dialog dlg = wx.MessageDialog(self.frame, "Download stopped on error: %s" % repr(ds.get_error()), "Download Error", wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() # Pass DownloadStates to libaryView no_collected_list = [ds for ds in dslist] try: # Arno, 2012-07-17: Retrieving peerlist for the DownloadStates takes CPU # so only do it when needed for display. wantpeers.extend(self.guiUtility.library_manager.download_state_callback(no_collected_list)) except: print_exc() # Check to see if a download has finished newActiveDownloads = [] doCheckpoint = False seeding_download_list = [] for ds in dslist: state = ds.get_status() download = ds.get_download() tdef = download.get_def() safename = tdef.get_name_as_unicode() if state == DLSTATUS_DOWNLOADING: newActiveDownloads.append(safename) elif state == DLSTATUS_SEEDING: seeding_download_list.append({u'infohash': tdef.get_infohash(), u'download': download, }) if safename in self.prevActiveDownloads: infohash = tdef.get_infohash() self.utility.session.notifier.notify(NTFY_TORRENTS, NTFY_FINISHED, infohash, safename) doCheckpoint = True elif download.get_hops() == 0 and download.get_safe_seeding(): self._logger.info("Re-add torrent with default nr of hops to prevent naked seeding") self.utility.session.remove_download(download) # copy the old download_config and change the hop count dscfg = download.copy() dscfg.set_hops(self.utility.read_config('default_number_hops')) # TODO(emilon): That's a hack to work around the fact # that removing a torrent is racy. self.utility.session.lm.threadpool.call(0.5, reactor.callInThread, self.utility.session.start_download, tdef, dscfg) self.prevActiveDownloads = newActiveDownloads if doCheckpoint: self.utility.session.checkpoint() if self.utility.read_config(u'seeding_mode') == 'never': for data in seeding_download_list: data[u'download'].stop() from Tribler.Main.vwxGUI.UserDownloadChoice import UserDownloadChoice UserDownloadChoice.get_singleton().set_download_state(data[u'infohash'], "stop") # Adjust speeds and call TunnelCommunity.monitor_downloads once every 4 seconds adjustspeeds = False if self.ratestatecallbackcount % 4 == 0: adjustspeeds = True if adjustspeeds and self.tunnel_community: self.tunnel_community.monitor_downloads(dslist) except: print_exc() return 1.0, wantpeers def loadSessionCheckpoint(self): pstate_dir = self.utility.session.get_downloads_pstate_dir() filelist = os.listdir(pstate_dir) if any([filename.endswith('.pickle') for filename in filelist]): convertDownloadCheckpoints(pstate_dir) from Tribler.Main.vwxGUI.UserDownloadChoice import UserDownloadChoice user_download_choice = UserDownloadChoice.get_singleton() initialdlstatus_dict = {} for infohash, state in user_download_choice.get_download_states().iteritems(): if state == 'stop': initialdlstatus_dict[infohash] = DLSTATUS_STOPPED self.utility.session.load_checkpoint(initialdlstatus_dict=initialdlstatus_dict) def guiservthread_free_space_check(self): if not (self and self.frame and self.frame.SRstatusbar): return free_space = get_free_space(DefaultDownloadStartupConfig.getInstance().get_dest_dir()) self.frame.SRstatusbar.RefreshFreeSpace(free_space) storage_locations = defaultdict(list) for download in self.utility.session.get_downloads(): if download.get_status() == DLSTATUS_DOWNLOADING: storage_locations[download.get_dest_dir()].append(download) show_message = False low_on_space = [ path for path in storage_locations.keys( ) if 0 < get_free_space( path) < self.utility.read_config( 'free_space_threshold')] for path in low_on_space: for download in storage_locations[path]: download.stop() show_message = True if show_message: wx.CallAfter(wx.MessageBox, "Tribler has detected low disk space. Related downloads have been stopped.", "Error") self.utility.session.lm.threadpool.call_in_thread(FREE_SPACE_CHECK_INTERVAL, self.guiservthread_free_space_check) def guiservthread_checkpoint_timer(self): """ Periodically checkpoint Session """ if self.done: return try: self._logger.info("main: Checkpointing Session") self.utility.session.checkpoint() self.utility.session.lm.threadpool.call_in_thread(SESSION_CHECKPOINT_INTERVAL, self.guiservthread_checkpoint_timer) except: print_exc() @forceWxThread def sesscb_ntfy_activities(self, events): if self._frame_and_ready(): for args in events: objectID = args[2] args = args[3:] self.frame.setActivity(objectID, *args) @forceWxThread def sesscb_ntfy_reachable(self, subject, changeType, objectID, msg): if self._frame_and_ready(): self.frame.SRstatusbar.onReachable() @forceWxThread def sesscb_ntfy_channelupdates(self, events): if self._frame_and_ready(): for args in events: subject = args[0] changeType = args[1] objectID = args[2] if self.frame.channellist: if len(args) > 3: myvote = args[3] else: myvote = False manager = self.frame.channellist.GetManager() manager.channelUpdated(objectID, subject == NTFY_VOTECAST, myvote=myvote) manager = self.frame.selectedchannellist.GetManager() manager.channelUpdated( objectID, stateChanged=changeType == NTFY_STATE, modified=changeType == NTFY_MODIFIED) if changeType == NTFY_CREATE: if self.frame.channellist: self.frame.channellist.SetMyChannelId(objectID) self.torrentfeed.register(self.utility.session, objectID) self.torrentfeed.addCallback(objectID, self.guiUtility.channelsearch_manager.createTorrentFromDef) self.frame.managechannel.channelUpdated( objectID, created=changeType == NTFY_CREATE, modified=changeType == NTFY_MODIFIED) @forceWxThread def sesscb_ntfy_torrentupdates(self, events): if self._frame_and_ready(): infohashes = [args[2] for args in events] if self.frame.searchlist: manager = self.frame.searchlist.GetManager() manager.torrentsUpdated(infohashes) manager = self.frame.selectedchannellist.GetManager() manager.torrentsUpdated(infohashes) manager = self.frame.playlist.GetManager() manager.torrentsUpdated(infohashes) manager = self.frame.librarylist.GetManager() manager.torrentsUpdated(infohashes) from Tribler.Main.Utility.GuiDBTuples import CollectedTorrent if self.frame.torrentdetailspanel.torrent and self.frame.torrentdetailspanel.torrent.infohash in infohashes: # If an updated torrent is being shown in the detailspanel, make sure the information gets refreshed. t = self.frame.torrentdetailspanel.torrent torrent = t.torrent if isinstance(t, CollectedTorrent) else t self.frame.torrentdetailspanel.setTorrent(torrent) if self.frame.librarydetailspanel.torrent and self.frame.librarydetailspanel.torrent.infohash in infohashes: t = self.frame.librarydetailspanel.torrent torrent = t.torrent if isinstance(t, CollectedTorrent) else t self.frame.librarydetailspanel.setTorrent(torrent) def sesscb_ntfy_torrentfinished(self, subject, changeType, objectID, *args): self.guiUtility.Notify( "Download Completed", "Torrent '%s' has finished downloading. Now seeding." % args[0], icon='seed') if self._frame_and_ready(): infohash = objectID torrent = self.guiUtility.torrentsearch_manager.getTorrentByInfohash(infohash) self.guiUtility.library_manager.addDownloadState(torrent) def sesscb_ntfy_magnet(self, subject, changetype, objectID, *args): if changetype == NTFY_MAGNET_STARTED: self.guiUtility.library_manager.magnet_started(objectID) elif changetype == NTFY_MAGNET_GOT_PEERS: self.guiUtility.library_manager.magnet_got_peers(objectID, args[0]) elif changetype == NTFY_MAGNET_CLOSE: self.guiUtility.library_manager.magnet_close(objectID) @forceWxThread def sesscb_ntfy_playlistupdates(self, subject, changeType, objectID, *args): if self._frame_and_ready(): if changeType == NTFY_INSERT: self.frame.managechannel.playlistCreated(objectID) manager = self.frame.selectedchannellist.GetManager() manager.playlistCreated(objectID) else: self.frame.managechannel.playlistUpdated(objectID, modified=changeType == NTFY_MODIFIED) if len(args) > 0: infohash = args[0] else: infohash = False manager = self.frame.selectedchannellist.GetManager() manager.playlistUpdated(objectID, infohash, modified=changeType == NTFY_MODIFIED) manager = self.frame.playlist.GetManager() manager.playlistUpdated(objectID, modified=changeType == NTFY_MODIFIED) @forceWxThread def sesscb_ntfy_commentupdates(self, subject, changeType, objectID, *args): if self._frame_and_ready(): self.frame.selectedchannellist.OnCommentCreated(objectID) self.frame.playlist.OnCommentCreated(objectID) @forceWxThread def sesscb_ntfy_modificationupdates(self, subject, changeType, objectID, *args): if self._frame_and_ready(): self.frame.selectedchannellist.OnModificationCreated(objectID) self.frame.playlist.OnModificationCreated(objectID) @forceWxThread def sesscb_ntfy_moderationupdats(self, subject, changeType, objectID, *args): if self._frame_and_ready(): self.frame.selectedchannellist.OnModerationCreated(objectID) self.frame.playlist.OnModerationCreated(objectID) @forceWxThread def sesscb_ntfy_markingupdates(self, subject, changeType, objectID, *args): if self._frame_and_ready(): self.frame.selectedchannellist.OnMarkingCreated(objectID) self.frame.playlist.OnModerationCreated(objectID) @forceWxThread def onError(self, e): print_exc() _, value, stack = sys.exc_info() backtrace = traceback.format_exception(type, value, stack) win = FeedbackWindow("Unfortunately, Tribler ran into an internal error") win.CreateOutputWindow('') for line in backtrace: win.write(line) win.ShowModal() @forceWxThread def OnExit(self): bm = self.gui_image_manager.getImage(u'closescreen.png') self.closewindow = GaugeSplash(bm, "Closing...", 6) self.closewindow.Show() self._logger.info("main: ONEXIT") self.ready = False self.done = True # write all persistent data to disk self.closewindow.tick('Write all persistent data to disk') if self.torrentfeed: self.torrentfeed.shutdown() self.torrentfeed.delInstance() if self.webUI: self.webUI.stop() self.webUI.delInstance() if self.frame: self.frame.Destroy() self.frame = None # Don't checkpoint, interferes with current way of saving Preferences, # see Tribler/Main/Dialogs/abcoption.py if self.utility: # Niels: lets add a max waiting time for this session shutdown. session_shutdown_start = time() try: self._logger.info("ONEXIT cleaning database") self.closewindow.tick('Cleaning database') torrent_db = self.utility.session.open_dbhandler(NTFY_TORRENTS) torrent_db._db.clean_db(randint(0, 24) == 0, exiting=True) except: print_exc() self.closewindow.tick('Shutdown session') self.utility.session.shutdown(hacksessconfcheckpoint=False) # Arno, 2012-07-12: Shutdown should be quick # Niels, 2013-03-21: However, setting it too low will prevent checkpoints from being written to disk waittime = 60 while not self.utility.session.has_shutdown(): diff = time() - session_shutdown_start if diff > waittime: self._logger.info("main: ONEXIT NOT Waiting for Session to shutdown, took too long") break self._logger.info( "ONEXIT Waiting for Session to shutdown, will wait for an additional %d seconds", waittime - diff) sleep(3) self._logger.info("ONEXIT Session is shutdown") self.closewindow.tick('Deleting instances') self._logger.debug("ONEXIT deleting instances") Session.del_instance() GUIUtility.delInstance() GUIDBProducer.delInstance() DefaultDownloadStartupConfig.delInstance() GuiImageManager.delInstance() self.closewindow.tick('Exiting now') self.closewindow.Destroy() return 0 def db_exception_handler(self, e): self._logger.debug("Database Exception handler called %s value %s #", e, e.args) try: if e.args[1] == "DB object has been closed": return # We caused this non-fatal error, don't show. if self.error is not None and self.error.args[1] == e.args[1]: return # don't repeat same error except: self._logger.error("db_exception_handler error %s %s", e, type(e)) print_exc() # print_stack() self.onError(e) def getConfigPath(self): return self.utility.getConfigPath() def startWithRightView(self): if self.params[0] != "": self.guiUtility.ShowPage('my_files') def i2ithread_readlinecallback(self, ic, cmd): """ Called by Instance2Instance thread """ self._logger.info("main: Another instance called us with cmd %s", cmd) ic.close() if cmd.startswith('START '): param = cmd[len('START '):].strip().decode("utf-8") torrentfilename = None if param.startswith('http:'): # Retrieve from web f = tempfile.NamedTemporaryFile() n = urllib2.urlopen(param) data = n.read() f.write(data) f.close() n.close() torrentfilename = f.name else: torrentfilename = param # Switch to GUI thread # New for 5.0: Start in VOD mode def start_asked_download(): if torrentfilename.startswith("magnet:"): self.frame.startDownloadFromMagnet(torrentfilename) else: self.frame.startDownload(torrentfilename) self.guiUtility.ShowPage('my_files') wx.CallAfter(start_asked_download)
class TestAsServer(AbstractServer): """ Parent class for testing the server-side of Tribler """ def setUp(self): super(TestAsServer, self).setUp(annotate=False) self.setUpPreSession() self.quitting = False self.session = Session(self.config) upgrader = self.session.prestart() while not upgrader.is_done: time.sleep(0.1) assert not upgrader.failed, upgrader.current_status self.session.start() self.hisport = self.session.get_listen_port() while not self.session.lm.initComplete: time.sleep(1) self.annotate(self._testMethodName, start=True) def setUpPreSession(self): """ Should set self.config_path and self.config """ self.config = SessionStartupConfig() self.config.set_state_dir(self.getStateDir()) self.config.set_torrent_checking(False) self.config.set_multicast_local_peer_discovery(False) self.config.set_megacache(False) self.config.set_dispersy(False) self.config.set_mainline_dht(False) self.config.set_torrent_store(False) self.config.set_enable_torrent_search(False) self.config.set_enable_channel_search(False) self.config.set_torrent_collecting(False) self.config.set_libtorrent(False) self.config.set_dht_torrent_collecting(False) self.config.set_videoplayer(False) self.config.set_enable_metadata(False) self.config.set_upgrader_enabled(False) def tearDown(self): self.annotate(self._testMethodName, start=False) """ unittest test tear down code """ if self.session is not None: self._shutdown_session(self.session) Session.del_instance() time.sleep(10) gc.collect() ts = enumerate_threads() self._logger.debug("test_as_server: Number of threads still running %d", len(ts)) for t in ts: self._logger.debug("Thread still running %s, daemon: %s, instance: %s", t.getName(), t.isDaemon(), t) super(TestAsServer, self).tearDown(annotate=False) def _shutdown_session(self, session): session_shutdown_start = time.time() waittime = 60 session.shutdown() while not session.has_shutdown(): diff = time.time() - session_shutdown_start assert diff < waittime, "test_as_server: took too long for Session to shutdown" self._logger.debug( "Waiting for Session to shutdown, will wait for an additional %d seconds", (waittime - diff)) wx.SafeYield() time.sleep(1) self._logger.debug("Session has shut down") def assert_(self, boolean, reason=None, do_assert=True, tribler_session=None, dump_statistics=False): if not boolean: # print statistics if needed if tribler_session and dump_statistics: self._print_statistics(tribler_session.get_statistics()) self.quit() assert boolean, reason @blocking_call_on_reactor_thread def _print_statistics(self, statistics_dict): def _print_data_dict(data_dict, level): for k, v in data_dict.iteritems(): indents = u'-' + u'-' * 2 * level if isinstance(v, basestring): self._logger.debug(u"%s %s: %s", indents, k, v) elif isinstance(v, dict): self._logger.debug(u"%s %s:", indents, k) _print_data_dict(v, level + 1) else: # ignore other types for the moment continue self._logger.debug(u"========== Tribler Statistics BEGIN ==========") _print_data_dict(statistics_dict, 0) self._logger.debug(u"========== Tribler Statistics END ==========") def startTest(self, callback): self.quitting = False callback() def callLater(self, seconds, callback): if not self.quitting: if seconds: time.sleep(seconds) callback() def CallConditional(self, timeout, condition, callback, assert_message=None, assert_callback=None, tribler_session=None, dump_statistics=False): t = time.time() def DoCheck(): if not self.quitting: # only use the last two parts as the ID because the full name is too long test_id = self.id() test_id = '.'.join(test_id.split('.')[-2:]) if time.time() - t < timeout: try: if condition(): self._logger.debug("%s - condition satisfied after %d seconds, calling callback '%s'", test_id, time.time() - t, callback.__name__) callback() else: self.callLater(0.5, DoCheck) except: print_exc() self.assert_(False, '%s - Condition or callback raised an exception, quitting (%s)' % (test_id, assert_message or "no-assert-msg"), do_assert=False) else: self._logger.debug("%s - %s, condition was not satisfied in %d seconds (%s)", test_id, ('calling callback' if assert_callback else 'quitting'), timeout, assert_message or "no-assert-msg") assertcall = assert_callback if assert_callback else self.assert_ kwargs = {} if assertcall == self.assert_: kwargs = {'tribler_session': tribler_session, 'dump_statistics': dump_statistics} assertcall(False, "%s - %s - Condition was not satisfied in %d seconds" % (test_id, assert_message, timeout), do_assert=False, **kwargs) self.callLater(0, DoCheck) def quit(self): self.quitting = True
class ABCApp(object): def __init__(self, params, installdir, autoload_discovery=True, use_torrent_search=True, use_channel_search=True): assert not isInIOThread( ), "isInIOThread() seems to not be working correctly" self._logger = logging.getLogger(self.__class__.__name__) self.params = params self.installdir = installdir self.state_dir = None self.error = None self.last_update = 0 self.ready = False self.done = False self.frame = None self.upgrader = None self.said_start_playback = False self.decodeprogress = 0 self.old_reputation = 0 # DISPERSY will be set when available self.dispersy = None # BARTER_COMMUNITY will be set when both Dispersy and the EffortCommunity are available self.barter_community = None self.tunnel_community = None self.torrentfeed = None self.webUI = None self.utility = None # Stage 1 start session = self.InitStage1(installdir, autoload_discovery=autoload_discovery, use_torrent_search=use_torrent_search, use_channel_search=use_channel_search) self.splash = None try: bm = self.gui_image_manager.getImage(u'splash.png') self.splash = GaugeSplash(bm, "Loading...", 13) self.splash.Show() self._logger.info('Client Starting Up.') self._logger.info("Tribler is using %s as working directory", self.installdir) # Stage 2: show the splash window and start the session self.splash.tick('Starting API') s = self.startAPI(session, self.splash.tick) self.utility = Utility(self.installdir, s.get_state_dir()) if self.utility.read_config(u'saveas', u'downloadconfig'): DefaultDownloadStartupConfig.getInstance().set_dest_dir( self.utility.read_config(u'saveas', u'downloadconfig')) self.utility.set_app(self) self.utility.set_session(s) self.guiUtility = GUIUtility.getInstance(self.utility, self.params, self) GUIDBProducer.getInstance() self._logger.info('Tribler Version: %s Build: %s', version_id, commit_id) version_info = self.utility.read_config('version_info') if version_info.get('version_id', None) != version_id: # First run of a different version version_info['first_run'] = int(time()) version_info['version_id'] = version_id self.utility.write_config('version_info', version_info) self.splash.tick( 'Starting session and upgrading database (it may take a while)' ) s.start() self.dispersy = s.lm.dispersy self.splash.tick('Loading userdownloadchoice') from Tribler.Main.vwxGUI.UserDownloadChoice import UserDownloadChoice UserDownloadChoice.get_singleton().set_utility(self.utility) self.splash.tick('Initializing Family Filter') cat = Category.getInstance(session) state = self.utility.read_config('family_filter') if state in (1, 0): cat.set_family_filter(state == 1) else: self.utility.write_config('family_filter', 1) self.utility.flush_config() cat.set_family_filter(True) # Create global speed limits self.splash.tick('Setting up speed limits') # Counter to suppress some event from occurring self.ratestatecallbackcount = 0 maxup = self.utility.read_config('maxuploadrate') maxdown = self.utility.read_config('maxdownloadrate') # set speed limits using LibtorrentMgr s.set_max_upload_speed(maxup) s.set_max_download_speed(maxdown) # Only allow updates to come in after we defined ratelimiter self.prevActiveDownloads = [] s.set_download_states_callback(self.sesscb_states_callback) # Schedule task for checkpointing Session, to avoid hash checks after # crashes. startWorker(consumer=None, workerFn=self.guiservthread_checkpoint_timer, delay=SESSION_CHECKPOINT_INTERVAL) if not ALLOW_MULTIPLE: # Put it here so an error is shown in the startup-error popup # Start server for instance2instance communication Instance2InstanceServer( self.utility.read_config('i2ilistenport'), self.i2ithread_readlinecallback) self.splash.tick('GUIUtility register') self.guiUtility.register() self.frame = MainFrame( self, None, PLAYBACKMODE_INTERNAL in return_feasible_playback_modes(), self.splash.tick) self.frame.SetIcon( wx.Icon( os.path.join(self.installdir, 'Tribler', 'Main', 'vwxGUI', 'images', 'tribler.ico'), wx.BITMAP_TYPE_ICO)) # Arno, 2011-06-15: VLC 1.1.10 pops up separate win, don't have two. self.frame.videoframe = None if PLAYBACKMODE_INTERNAL in return_feasible_playback_modes(): vlcwrap = s.lm.videoplayer.get_vlcwrap() wx.CallLater(3000, vlcwrap._init_vlc) self.frame.videoframe = VideoDummyFrame( self.frame.videoparentpanel, self.utility, vlcwrap) if sys.platform == 'win32': wx.CallAfter(self.frame.top_bg.Refresh) wx.CallAfter(self.frame.top_bg.Layout) else: self.frame.top_bg.Layout() # Arno, 2007-05-03: wxWidgets 2.8.3.0 and earlier have the MIME-type for .bmp # files set to 'image/x-bmp' whereas 'image/bmp' is the official one. try: bmphand = None hands = wx.Image.GetHandlers() for hand in hands: # print "Handler",hand.GetExtension(),hand.GetType(),hand.GetMimeType() if hand.GetMimeType() == 'image/x-bmp': bmphand = hand break # wx.Image.AddHandler() if bmphand is not None: bmphand.SetMimeType('image/bmp') except: # wx < 2.7 don't like wx.Image.GetHandlers() print_exc() self.splash.Destroy() self.frame.Show(True) session.lm.threadpool.call_in_thread( 0, self.guiservthread_free_space_check) self.torrentfeed = RssParser.getInstance() self.webUI = None if self.utility.read_config('use_webui'): try: from Tribler.Main.webUI.webUI import WebUI self.webUI = WebUI.getInstance( self.guiUtility.library_manager, self.guiUtility.torrentsearch_manager, self.utility.read_config('webui_port')) self.webUI.start() except Exception: print_exc() self.emercoin_mgr = None try: from Tribler.Main.Emercoin.EmercoinMgr import EmercoinMgr self.emercoin_mgr = EmercoinMgr(self.utility) except Exception: print_exc() wx.CallAfter(self.PostInit2) # 08/02/10 Boudewijn: Working from home though console # doesn't allow me to press close. The statement below # gracefully closes Tribler after 120 seconds. # wx.CallLater(120*1000, wx.GetApp().Exit) self.ready = True except Exception as e: if self.splash: self.splash.Destroy() self.onError(e) def InitStage1(self, installdir, autoload_discovery=True, use_torrent_search=True, use_channel_search=True): """ Stage 1 start: pre-start the session to handle upgrade. """ self.gui_image_manager = GuiImageManager.getInstance(installdir) # Start Tribler Session defaultConfig = SessionStartupConfig() state_dir = defaultConfig.get_state_dir() # Switch to the state dir so relative paths can be used (IE, in LevelDB store paths) if not os.path.exists(state_dir): os.makedirs(state_dir) os.chdir(state_dir) cfgfilename = Session.get_default_config_filename(state_dir) self._logger.debug(u"Session config %s", cfgfilename) try: self.sconfig = SessionStartupConfig.load(cfgfilename) except: try: self.sconfig = convertSessionConfig( os.path.join(state_dir, 'sessconfig.pickle'), cfgfilename) convertMainConfig(state_dir, os.path.join(state_dir, 'abc.conf'), os.path.join(state_dir, STATEDIR_GUICONFIG)) except: self.sconfig = SessionStartupConfig() self.sconfig.set_state_dir(state_dir) self.sconfig.set_install_dir(self.installdir) # TODO(emilon): Do we still want to force limit this? With the new # torrent store it should be pretty fast even with more that that. # Arno, 2010-03-31: Hard upgrade to 50000 torrents collected self.sconfig.set_torrent_collecting_max_torrents(50000) dlcfgfilename = get_default_dscfg_filename( self.sconfig.get_state_dir()) self._logger.debug("main: Download config %s", dlcfgfilename) try: defaultDLConfig = DefaultDownloadStartupConfig.load(dlcfgfilename) except: try: defaultDLConfig = convertDefaultDownloadConfig( os.path.join(state_dir, 'dlconfig.pickle'), dlcfgfilename) except: defaultDLConfig = DefaultDownloadStartupConfig.getInstance() if not defaultDLConfig.get_dest_dir(): defaultDLConfig.set_dest_dir(get_default_dest_dir()) if not os.path.isdir(defaultDLConfig.get_dest_dir()): try: os.makedirs(defaultDLConfig.get_dest_dir()) except: # Could not create directory, ask user to select a different location dlg = wx.DirDialog( None, "Could not find download directory, please select a new location to store your downloads", style=wx.DEFAULT_DIALOG_STYLE) dlg.SetPath(get_default_dest_dir()) if dlg.ShowModal() == wx.ID_OK: new_dest_dir = dlg.GetPath() defaultDLConfig.set_dest_dir(new_dest_dir) defaultDLConfig.save(dlcfgfilename) self.sconfig.save(cfgfilename) else: # Quit self.onError = lambda e: self._logger.error( "tribler: quitting due to non-existing destination directory" ) raise Exception() if not use_torrent_search: self.sconfig.set_enable_torrent_search(False) if not use_channel_search: self.sconfig.set_enable_channel_search(False) session = Session(self.sconfig, autoload_discovery=autoload_discovery) session.add_observer(self.show_upgrade_dialog, NTFY_UPGRADER, [NTFY_STARTED]) self.upgrader = session.prestart() while not self.upgrader.is_done: wx.SafeYield() sleep(0.1) return session @forceWxThread def show_upgrade_dialog(self, subject, changetype, objectID, *args): assert wx.Thread_IsMain() upgrade_dialog = TriblerUpgradeDialog(self.gui_image_manager, self.upgrader) failed = upgrade_dialog.ShowModal() upgrade_dialog.Destroy() if failed: wx.MessageDialog( None, "Failed to upgrade the on disk data.\n\n" "Tribler has backed up the old data and will now start from scratch.\n\n" "Get in contact with the Tribler team if you want to help debugging this issue.\n\n" "Error was: %s" % self.upgrader.current_status, "Data format upgrade failed", wx.OK | wx.CENTRE | wx.ICON_EXCLAMATION).ShowModal() def _frame_and_ready(self): return self.ready and self.frame and self.frame.ready def PostInit2(self): self.frame.Raise() self.startWithRightView() self.set_reputation() s = self.utility.session s.add_observer(self.sesscb_ntfy_reachable, NTFY_REACHABLE, [NTFY_INSERT]) s.add_observer(self.sesscb_ntfy_activities, NTFY_ACTIVITIES, [NTFY_INSERT], cache=10) s.add_observer( self.sesscb_ntfy_channelupdates, NTFY_CHANNELCAST, [NTFY_INSERT, NTFY_UPDATE, NTFY_CREATE, NTFY_STATE, NTFY_MODIFIED], cache=10) s.add_observer(self.sesscb_ntfy_channelupdates, NTFY_VOTECAST, [NTFY_UPDATE], cache=10) s.add_observer(self.sesscb_ntfy_myprefupdates, NTFY_MYPREFERENCES, [NTFY_INSERT, NTFY_UPDATE, NTFY_DELETE]) s.add_observer(self.sesscb_ntfy_torrentupdates, NTFY_TORRENTS, [NTFY_UPDATE, NTFY_INSERT], cache=10) s.add_observer(self.sesscb_ntfy_playlistupdates, NTFY_PLAYLISTS, [NTFY_INSERT, NTFY_UPDATE]) s.add_observer(self.sesscb_ntfy_commentupdates, NTFY_COMMENTS, [NTFY_INSERT, NTFY_DELETE]) s.add_observer(self.sesscb_ntfy_modificationupdates, NTFY_MODIFICATIONS, [NTFY_INSERT]) s.add_observer(self.sesscb_ntfy_moderationupdats, NTFY_MODERATIONS, [NTFY_INSERT]) s.add_observer(self.sesscb_ntfy_markingupdates, NTFY_MARKINGS, [NTFY_INSERT]) s.add_observer(self.sesscb_ntfy_torrentfinished, NTFY_TORRENTS, [NTFY_FINISHED]) s.add_observer( self.sesscb_ntfy_magnet, NTFY_TORRENTS, [NTFY_MAGNET_GOT_PEERS, NTFY_MAGNET_STARTED, NTFY_MAGNET_CLOSE]) # TODO(emilon): Use the LogObserver I already implemented # self.dispersy.callback.attach_exception_handler(self.frame.exceptionHandler) startWorker(None, self.loadSessionCheckpoint, delay=5.0, workerType="ThreadPool") # initialize the torrent feed thread channelcast = s.open_dbhandler(NTFY_CHANNELCAST) def db_thread(): return channelcast.getMyChannelId() def wx_thread(delayedResult): my_channel = delayedResult.get() if my_channel: self.torrentfeed.register(self.utility.session, my_channel) self.torrentfeed.addCallback( my_channel, self.guiUtility.channelsearch_manager.createTorrentFromDef) startWorker(wx_thread, db_thread, delay=5.0) def startAPI(self, session, progress): @call_on_reactor_thread def define_communities(*args): assert isInIOThread() from Tribler.community.channel.community import ChannelCommunity from Tribler.community.channel.preview import PreviewChannelCommunity from Tribler.community.tunnel.tunnel_community import TunnelSettings from Tribler.community.tunnel.hidden_community import HiddenTunnelCommunity # make sure this is only called once session.remove_observer(define_communities) dispersy = session.get_dispersy_instance() self._logger.info("tribler: Preparing communities...") now = time() dispersy.attach_progress_handler(self.progressHandler) default_kwargs = {'tribler_session': session} # must be called on the Dispersy thread if session.get_barter_community_enabled(): from Tribler.community.bartercast4.community import BarterCommunity dispersy.define_auto_load(BarterCommunity, session.dispersy_member, load=True) # load metadata community dispersy.define_auto_load(ChannelCommunity, session.dispersy_member, load=True, kargs=default_kwargs) dispersy.define_auto_load(PreviewChannelCommunity, session.dispersy_member, kargs=default_kwargs) keypair = dispersy.crypto.generate_key(u"curve25519") dispersy_member = dispersy.get_member( private_key=dispersy.crypto.key_to_bin(keypair), ) settings = TunnelSettings(session.get_install_dir(), tribler_session=session) tunnel_kwargs = {'tribler_session': session, 'settings': settings} self.tunnel_community = dispersy.define_auto_load( HiddenTunnelCommunity, dispersy_member, load=True, kargs=tunnel_kwargs)[0] session.set_anon_proxy_settings( 2, ("127.0.0.1", session.get_tunnel_community_socks5_listen_ports())) diff = time() - now self._logger.info("tribler: communities are ready in %.2f seconds", diff) session.add_observer(define_communities, NTFY_DISPERSY, [NTFY_STARTED]) return session @forceWxThread def sesscb_ntfy_myprefupdates(self, subject, changeType, objectID, *args): if self._frame_and_ready(): if changeType in [NTFY_INSERT, NTFY_UPDATE]: if changeType == NTFY_INSERT: if self.frame.searchlist: manager = self.frame.searchlist.GetManager() manager.downloadStarted(objectID) manager = self.frame.selectedchannellist.GetManager() manager.downloadStarted(objectID) manager = self.frame.librarylist.GetManager() manager.downloadStarted(objectID) elif changeType == NTFY_DELETE: self.guiUtility.frame.librarylist.RemoveItem(objectID) if self.guiUtility.frame.librarylist.IsShownOnScreen() and \ self.guiUtility.frame.librarydetailspanel.torrent and \ self.guiUtility.frame.librarydetailspanel.torrent.infohash == objectID: self.guiUtility.frame.librarylist.ResetBottomWindow() self.guiUtility.frame.top_bg.ClearButtonHandlers() if self.guiUtility.frame.librarylist.list.IsEmpty(): self.guiUtility.frame.librarylist.SetData([]) def progressHandler(self, title, message, maximum): from Tribler.Main.Dialogs.ThreadSafeProgressDialog import ThreadSafeProgressDialog return ThreadSafeProgressDialog( title, message, maximum, None, wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME | wx.PD_ESTIMATED_TIME | wx.PD_REMAINING_TIME | wx.PD_AUTO_HIDE) def set_reputation(self): def do_db(): nr_connections = 0 nr_channel_connections = 0 if self.dispersy: for community in self.dispersy.get_communities(): from Tribler.community.search.community import SearchCommunity from Tribler.community.allchannel.community import AllChannelCommunity if isinstance(community, SearchCommunity): nr_connections = community.get_nr_connections() elif isinstance(community, AllChannelCommunity): nr_channel_connections = community.get_nr_connections() return nr_connections, nr_channel_connections def do_wx(delayedResult): if not self.frame: return nr_connections, nr_channel_connections = delayedResult.get() # self.frame.SRstatusbar.set_reputation(myRep, total_down, total_up) # bitmap is 16px wide, -> but first and last pixel do not add anything. percentage = min(1.0, (nr_connections + 1) / 16.0) self.frame.SRstatusbar.SetConnections(percentage, nr_connections, nr_channel_connections) """ set the reputation in the GUI""" if self._frame_and_ready(): startWorker(do_wx, do_db, uId=u"tribler.set_reputation") startWorker(None, self.set_reputation, delay=5.0, workerType="ThreadPool") def sesscb_states_callback(self, dslist): if not self.ready: return 5.0, [] wantpeers = [] self.ratestatecallbackcount += 1 try: # Print stats on Console if self.ratestatecallbackcount % 5 == 0: for ds in dslist: safename = repr(ds.get_download().get_def().get_name()) self._logger.debug("%s %s %.1f%% dl %.1f ul %.1f n %d", safename, dlstatus_strings[ds.get_status()], 100.0 * ds.get_progress(), ds.get_current_speed(DOWNLOAD), ds.get_current_speed(UPLOAD), ds.get_num_peers()) if ds.get_status() == DLSTATUS_STOPPED_ON_ERROR: self._logger.error("main: Error: %s", repr(ds.get_error())) download = self.utility.session.lm.downloads.get( ds.get_infohash()) if download: download.stop() # show error dialog dlg = wx.MessageDialog( self.frame, "Download stopped on error: %s" % repr(ds.get_error()), "Download Error", wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() # Pass DownloadStates to libaryView no_collected_list = [ds for ds in dslist] try: # Arno, 2012-07-17: Retrieving peerlist for the DownloadStates takes CPU # so only do it when needed for display. wantpeers.extend( self.guiUtility.library_manager.download_state_callback( no_collected_list)) except: print_exc() # Check to see if a download has finished newActiveDownloads = [] doCheckpoint = False seeding_download_list = [] for ds in dslist: state = ds.get_status() download = ds.get_download() tdef = download.get_def() safename = tdef.get_name_as_unicode() if state == DLSTATUS_DOWNLOADING: newActiveDownloads.append(safename) elif state == DLSTATUS_SEEDING: seeding_download_list.append({ u'infohash': tdef.get_infohash(), u'download': download, }) if safename in self.prevActiveDownloads: infohash = tdef.get_infohash() self.utility.session.notifier.notify( NTFY_TORRENTS, NTFY_FINISHED, infohash, safename) doCheckpoint = True elif download.get_hops( ) == 0 and download.get_safe_seeding(): self._logger.info( "Re-add torrent with default nr of hops to prevent naked seeding" ) self.utility.session.remove_download(download) # copy the old download_config and change the hop count dscfg = download.copy() dscfg.set_hops( self.utility.read_config('default_number_hops')) # TODO(emilon): That's a hack to work around the fact # that removing a torrent is racy. self.utility.session.lm.threadpool.call( 0.5, reactor.callInThread, self.utility.session.start_download, tdef, dscfg) self.prevActiveDownloads = newActiveDownloads if doCheckpoint: self.utility.session.checkpoint() if self.utility.read_config(u'seeding_mode') == 'never': for data in seeding_download_list: data[u'download'].stop() from Tribler.Main.vwxGUI.UserDownloadChoice import UserDownloadChoice UserDownloadChoice.get_singleton().set_download_state( data[u'infohash'], "stop") # Adjust speeds and call TunnelCommunity.monitor_downloads once every 4 seconds adjustspeeds = False if self.ratestatecallbackcount % 4 == 0: adjustspeeds = True if adjustspeeds and self.tunnel_community: self.tunnel_community.monitor_downloads(dslist) except: print_exc() return 1.0, wantpeers def loadSessionCheckpoint(self): pstate_dir = self.utility.session.get_downloads_pstate_dir() filelist = os.listdir(pstate_dir) if any([filename.endswith('.pickle') for filename in filelist]): convertDownloadCheckpoints(pstate_dir) from Tribler.Main.vwxGUI.UserDownloadChoice import UserDownloadChoice user_download_choice = UserDownloadChoice.get_singleton() initialdlstatus_dict = {} for infohash, state in user_download_choice.get_download_states( ).iteritems(): if state == 'stop': initialdlstatus_dict[infohash] = DLSTATUS_STOPPED self.utility.session.load_checkpoint( initialdlstatus_dict=initialdlstatus_dict) def guiservthread_free_space_check(self): if not (self and self.frame and self.frame.SRstatusbar): return free_space = get_free_space( DefaultDownloadStartupConfig.getInstance().get_dest_dir()) self.frame.SRstatusbar.RefreshFreeSpace(free_space) storage_locations = defaultdict(list) for download in self.utility.session.get_downloads(): if download.get_status() == DLSTATUS_DOWNLOADING: storage_locations[download.get_dest_dir()].append(download) show_message = False low_on_space = [ path for path in storage_locations.keys() if 0 < get_free_space( path) < self.utility.read_config('free_space_threshold') ] for path in low_on_space: for download in storage_locations[path]: download.stop() show_message = True if show_message: wx.CallAfter( wx.MessageBox, "Tribler has detected low disk space. Related downloads have been stopped.", "Error") self.utility.session.lm.threadpool.call_in_thread( FREE_SPACE_CHECK_INTERVAL, self.guiservthread_free_space_check) def guiservthread_checkpoint_timer(self): """ Periodically checkpoint Session """ if self.done: return try: self._logger.info("main: Checkpointing Session") self.utility.session.checkpoint() self.utility.session.lm.threadpool.call_in_thread( SESSION_CHECKPOINT_INTERVAL, self.guiservthread_checkpoint_timer) except: print_exc() @forceWxThread def sesscb_ntfy_activities(self, events): if self._frame_and_ready(): for args in events: objectID = args[2] args = args[3:] self.frame.setActivity(objectID, *args) @forceWxThread def sesscb_ntfy_reachable(self, subject, changeType, objectID, msg): if self._frame_and_ready(): self.frame.SRstatusbar.onReachable() @forceWxThread def sesscb_ntfy_channelupdates(self, events): if self._frame_and_ready(): for args in events: subject = args[0] changeType = args[1] objectID = args[2] if self.frame.channellist: if len(args) > 3: myvote = args[3] else: myvote = False manager = self.frame.channellist.GetManager() manager.channelUpdated(objectID, subject == NTFY_VOTECAST, myvote=myvote) manager = self.frame.selectedchannellist.GetManager() manager.channelUpdated(objectID, stateChanged=changeType == NTFY_STATE, modified=changeType == NTFY_MODIFIED) if changeType == NTFY_CREATE: if self.frame.channellist: self.frame.channellist.SetMyChannelId(objectID) self.torrentfeed.register(self.utility.session, objectID) self.torrentfeed.addCallback( objectID, self.guiUtility.channelsearch_manager. createTorrentFromDef) self.frame.managechannel.channelUpdated( objectID, created=changeType == NTFY_CREATE, modified=changeType == NTFY_MODIFIED) @forceWxThread def sesscb_ntfy_torrentupdates(self, events): if self._frame_and_ready(): infohashes = [args[2] for args in events] if self.frame.searchlist: manager = self.frame.searchlist.GetManager() manager.torrentsUpdated(infohashes) manager = self.frame.selectedchannellist.GetManager() manager.torrentsUpdated(infohashes) manager = self.frame.playlist.GetManager() manager.torrentsUpdated(infohashes) manager = self.frame.librarylist.GetManager() manager.torrentsUpdated(infohashes) from Tribler.Main.Utility.GuiDBTuples import CollectedTorrent if self.frame.torrentdetailspanel.torrent and self.frame.torrentdetailspanel.torrent.infohash in infohashes: # If an updated torrent is being shown in the detailspanel, make sure the information gets refreshed. t = self.frame.torrentdetailspanel.torrent torrent = t.torrent if isinstance(t, CollectedTorrent) else t self.frame.torrentdetailspanel.setTorrent(torrent) if self.frame.librarydetailspanel.torrent and self.frame.librarydetailspanel.torrent.infohash in infohashes: t = self.frame.librarydetailspanel.torrent torrent = t.torrent if isinstance(t, CollectedTorrent) else t self.frame.librarydetailspanel.setTorrent(torrent) def sesscb_ntfy_torrentfinished(self, subject, changeType, objectID, *args): self.guiUtility.Notify( "Download Completed", "Torrent '%s' has finished downloading. Now seeding." % args[0], icon='seed') if self._frame_and_ready(): infohash = objectID torrent = self.guiUtility.torrentsearch_manager.getTorrentByInfohash( infohash) self.guiUtility.library_manager.addDownloadState(torrent) def sesscb_ntfy_magnet(self, subject, changetype, objectID, *args): if changetype == NTFY_MAGNET_STARTED: self.guiUtility.library_manager.magnet_started(objectID) elif changetype == NTFY_MAGNET_GOT_PEERS: self.guiUtility.library_manager.magnet_got_peers(objectID, args[0]) elif changetype == NTFY_MAGNET_CLOSE: self.guiUtility.library_manager.magnet_close(objectID) @forceWxThread def sesscb_ntfy_playlistupdates(self, subject, changeType, objectID, *args): if self._frame_and_ready(): if changeType == NTFY_INSERT: self.frame.managechannel.playlistCreated(objectID) manager = self.frame.selectedchannellist.GetManager() manager.playlistCreated(objectID) else: self.frame.managechannel.playlistUpdated( objectID, modified=changeType == NTFY_MODIFIED) if len(args) > 0: infohash = args[0] else: infohash = False manager = self.frame.selectedchannellist.GetManager() manager.playlistUpdated(objectID, infohash, modified=changeType == NTFY_MODIFIED) manager = self.frame.playlist.GetManager() manager.playlistUpdated(objectID, modified=changeType == NTFY_MODIFIED) @forceWxThread def sesscb_ntfy_commentupdates(self, subject, changeType, objectID, *args): if self._frame_and_ready(): self.frame.selectedchannellist.OnCommentCreated(objectID) self.frame.playlist.OnCommentCreated(objectID) @forceWxThread def sesscb_ntfy_modificationupdates(self, subject, changeType, objectID, *args): if self._frame_and_ready(): self.frame.selectedchannellist.OnModificationCreated(objectID) self.frame.playlist.OnModificationCreated(objectID) @forceWxThread def sesscb_ntfy_moderationupdats(self, subject, changeType, objectID, *args): if self._frame_and_ready(): self.frame.selectedchannellist.OnModerationCreated(objectID) self.frame.playlist.OnModerationCreated(objectID) @forceWxThread def sesscb_ntfy_markingupdates(self, subject, changeType, objectID, *args): if self._frame_and_ready(): self.frame.selectedchannellist.OnMarkingCreated(objectID) self.frame.playlist.OnModerationCreated(objectID) @forceWxThread def onError(self, e): print_exc() _, value, stack = sys.exc_info() backtrace = traceback.format_exception(type, value, stack) win = FeedbackWindow( "Unfortunately, Tribler ran into an internal error") win.CreateOutputWindow('') for line in backtrace: win.write(line) win.ShowModal() @forceWxThread def OnExit(self): bm = self.gui_image_manager.getImage(u'closescreen.png') self.closewindow = GaugeSplash(bm, "Closing...", 6) self.closewindow.Show() self._logger.info("main: ONEXIT") self.ready = False self.done = True # write all persistent data to disk self.closewindow.tick('Write all persistent data to disk') if self.torrentfeed: self.torrentfeed.shutdown() self.torrentfeed.delInstance() if self.webUI: self.webUI.stop() self.webUI.delInstance() if self.frame: self.frame.Destroy() self.frame = None # Don't checkpoint, interferes with current way of saving Preferences, # see Tribler/Main/Dialogs/abcoption.py if self.utility: # Niels: lets add a max waiting time for this session shutdown. session_shutdown_start = time() try: self._logger.info("ONEXIT cleaning database") self.closewindow.tick('Cleaning database') torrent_db = self.utility.session.open_dbhandler(NTFY_TORRENTS) torrent_db._db.clean_db(randint(0, 24) == 0, exiting=True) except: print_exc() self.closewindow.tick('Shutdown session') self.utility.session.shutdown(hacksessconfcheckpoint=False) # Arno, 2012-07-12: Shutdown should be quick # Niels, 2013-03-21: However, setting it too low will prevent checkpoints from being written to disk waittime = 60 while not self.utility.session.has_shutdown(): diff = time() - session_shutdown_start if diff > waittime: self._logger.info( "main: ONEXIT NOT Waiting for Session to shutdown, took too long" ) break self._logger.info( "ONEXIT Waiting for Session to shutdown, will wait for an additional %d seconds", waittime - diff) sleep(3) self._logger.info("ONEXIT Session is shutdown") self.closewindow.tick('Deleting instances') self._logger.debug("ONEXIT deleting instances") Session.del_instance() GUIUtility.delInstance() GUIDBProducer.delInstance() DefaultDownloadStartupConfig.delInstance() GuiImageManager.delInstance() self.closewindow.tick('Exiting now') self.closewindow.Destroy() return 0 def db_exception_handler(self, e): self._logger.debug("Database Exception handler called %s value %s #", e, e.args) try: if e.args[1] == "DB object has been closed": return # We caused this non-fatal error, don't show. if self.error is not None and self.error.args[1] == e.args[1]: return # don't repeat same error except: self._logger.error("db_exception_handler error %s %s", e, type(e)) print_exc() # print_stack() self.onError(e) def getConfigPath(self): return self.utility.getConfigPath() def startWithRightView(self): if self.params[0] != "": self.guiUtility.ShowPage('my_files') def i2ithread_readlinecallback(self, ic, cmd): """ Called by Instance2Instance thread """ self._logger.info("main: Another instance called us with cmd %s", cmd) ic.close() if cmd.startswith('START '): param = cmd[len('START '):].strip().decode("utf-8") torrentfilename = None if param.startswith('http:'): # Retrieve from web f = tempfile.NamedTemporaryFile() n = urllib2.urlopen(param) data = n.read() f.write(data) f.close() n.close() torrentfilename = f.name else: torrentfilename = param # Switch to GUI thread # New for 5.0: Start in VOD mode def start_asked_download(): if torrentfilename.startswith("magnet:"): self.frame.startDownloadFromMagnet(torrentfilename) else: self.frame.startDownload(torrentfilename) self.guiUtility.ShowPage('my_files') wx.CallAfter(start_asked_download)
class TestAsServer(AbstractServer): """ Parent class for testing the server-side of Tribler """ @blocking_call_on_reactor_thread @inlineCallbacks def setUp(self, autoload_discovery=True): yield super(TestAsServer, self).setUp(annotate=False) self.setUpPreSession() self.quitting = False self.seeding_deferred = Deferred() self.seeder_session = None self.session = Session(self.config) self.tribler_started_deferred = self.session.start() yield self.tribler_started_deferred self.assertTrue(self.session.lm.initComplete) self.hisport = self.session.get_listen_port() self.annotate(self._testMethodName, start=True) def setUpPreSession(self): """ Should set self.config_path and self.config """ self.config = SessionStartupConfig() self.config.set_state_dir(self.getStateDir()) self.config.set_torrent_checking(False) self.config.set_multicast_local_peer_discovery(False) self.config.set_megacache(False) self.config.set_dispersy(False) self.config.set_mainline_dht(False) self.config.set_torrent_store(False) self.config.set_enable_torrent_search(False) self.config.set_enable_channel_search(False) self.config.set_torrent_collecting(False) self.config.set_libtorrent(False) self.config.set_dht_torrent_collecting(False) self.config.set_videoserver_enabled(False) self.config.set_enable_metadata(False) self.config.set_upgrader_enabled(False) self.config.set_http_api_enabled(False) self.config.set_tunnel_community_enabled(False) self.config.set_creditmining_enable(False) self.config.set_enable_multichain(False) @blocking_call_on_reactor_thread @inlineCallbacks def tearDown(self, annotate=True): self.annotate(self._testMethodName, start=False) """ unittest test tear down code """ if self.session is not None: assert self.session is Session.get_instance() yield self.session.shutdown() assert self.session.has_shutdown() Session.del_instance() yield self.stop_seeder() ts = enumerate_threads() self._logger.debug( "test_as_server: Number of threads still running %d", len(ts)) for t in ts: self._logger.debug( "Thread still running %s, daemon: %s, instance: %s", t.getName(), t.isDaemon(), t) yield super(TestAsServer, self).tearDown(annotate=False) def create_local_torrent(self, source_file): ''' This method creates a torrent from a local file and saves the torrent in the session state dir. Note that the source file needs to exist. ''' self.assertTrue(os.path.exists(source_file)) tdef = TorrentDef() tdef.add_content(source_file) tdef.set_tracker("http://localhost/announce") tdef.finalize() torrent_path = os.path.join(self.session.get_state_dir(), "seed.torrent") tdef.save(torrent_path) return tdef, torrent_path def setup_seeder(self, tdef, seed_dir): self.seed_config = SessionStartupConfig() self.seed_config.set_torrent_checking(False) self.seed_config.set_multicast_local_peer_discovery(False) self.seed_config.set_megacache(False) self.seed_config.set_dispersy(False) self.seed_config.set_mainline_dht(False) self.seed_config.set_torrent_store(False) self.seed_config.set_enable_torrent_search(False) self.seed_config.set_enable_channel_search(False) self.seed_config.set_torrent_collecting(False) self.seed_config.set_libtorrent(True) self.seed_config.set_dht_torrent_collecting(False) self.seed_config.set_videoserver_enabled(False) self.seed_config.set_enable_metadata(False) self.seed_config.set_upgrader_enabled(False) self.seed_config.set_tunnel_community_enabled(False) self.seed_config.set_state_dir(self.getStateDir(2)) def start_seed_download(_): self.dscfg_seed = DownloadStartupConfig() self.dscfg_seed.set_dest_dir(seed_dir) d = self.seeder_session.start_download_from_tdef( tdef, self.dscfg_seed) d.set_state_callback(self.seeder_state_callback) self._logger.debug( "starting to wait for download to reach seeding state") self.seeder_session = Session(self.seed_config, ignore_singleton=True) self.seeder_session.start().addCallback(start_seed_download) return self.seeding_deferred def stop_seeder(self): if self.seeder_session is not None: return self.seeder_session.shutdown() return succeed(None) def seeder_state_callback(self, ds): d = ds.get_download() self._logger.debug("seeder status: %s %s %s", repr(d.get_def().get_name()), dlstatus_strings[ds.get_status()], ds.get_progress()) if ds.get_status() == DLSTATUS_SEEDING: self.seeding_deferred.callback(None) return 0.0, False return 1.0, False