def _do_quit(self): self.dia.hide() if Bank.get() and Bank.get().is_starting(): Bank.get().stop() GlobalEvents.throw_event("quit_signal") #intentionally called twice, we dont want to be waiting around for bittorrent tracker shutdown if we havent even logged in GlobalEvents.throw_event("quit_signal")
def on_update(self): """Called periodically (once per second). Check whether we have run out of credits and if so, notifies the user and applications.""" Application.Application.on_update(self) if not self.isLoggedIn: return currentBalance = self.get_expected_balance() #if we have no credits and it's been a while (15 minutes) since we queried the bank, do that now: if currentBalance <= 0 and time.time( ) > self.balanceLastUpdatedAt + BALANCE_POLL_TIMEOUT: if not self.acoinDepositInProgress: self.acoinDepositInProgress = True self.deposit_acoins(None) #TODO: remove these from Global events #throw various balance related events if currentBalance <= 0: if self.creditStatus != "EMPTY": self.creditStatus = "EMPTY" GlobalEvents.throw_event("no_credits") elif currentBalance > MIN_FUNCTIONAL_MONEY: if self.creditStatus != "NORMAL": self.creditStatus = "NORMAL" GlobalEvents.throw_event("some_credits") else: self.creditStatus = "LOW"
def start(self): """Do the rest of the setup before turning control over to the reactor""" self._setup_environment() self._load_settings() self._load_data() self._create_applications() #in case this was the first run: self.bbApp.settings.fileName = os.path.join(Globals.USER_DATA_DIR, BitBlinder.BitBlinderSettings.defaultFile) GlobalEvents.throw_event("settings_changed") #must be done after settings are loaded self._start_psyco() #check for updates for the program: Updater.get().start() #start the bank bankStartupDeferred = self.bankApp.start() bankStartupDeferred.addCallback(self._on_bank_ready) bankStartupDeferred.addErrback(log_ex, "Bank failed to start!") #the rest of the startup code needs to run after the reactor has started: Scheduler.schedule_once(0.0, self._on_reactor_started)
def _on_bank_ready(self, result): """Called when the bank has finished starting. Alerts the applications to any startup arguments that were passed in, which will likely cause them to actually start.""" if result != True: log_msg("Bank failed to start correctly!", 0) return result #handle the starting arguments: Startup.handle_args(ProgramState.STARTING_DIR, sys.argv[1:]) GlobalEvents.throw_event("startup") #if this is the first run, save all the settings files: if self.bbApp.isFirstRun: for app in [self.bbApp, self.btApp, self.torApp, self.ffApp]: if app: app.settings.save() self.coreSettings.save() #schedule update function: def do_update(): BWHistory.update_all() return True ProgramState.DO_UPDATES = True self.updateEvent = Scheduler.schedule_repeat(Globals.INTERVAL_BETWEEN_UPDATES, do_update) return result
def start(self): """Do the rest of the setup before turning control over to the reactor""" self._setup_environment() self._load_settings() self._load_data() self._create_applications() #in case this was the first run: self.bbApp.settings.fileName = os.path.join( Globals.USER_DATA_DIR, BitBlinder.BitBlinderSettings.defaultFile) GlobalEvents.throw_event("settings_changed") #must be done after settings are loaded self._start_psyco() #check for updates for the program: Updater.get().start() #start the bank bankStartupDeferred = self.bankApp.start() bankStartupDeferred.addCallback(self._on_bank_ready) bankStartupDeferred.addErrback(log_ex, "Bank failed to start!") #the rest of the startup code needs to run after the reactor has started: Scheduler.schedule_once(0.0, self._on_reactor_started)
def _on_bank_ready(self, result): """Called when the bank has finished starting. Alerts the applications to any startup arguments that were passed in, which will likely cause them to actually start.""" if result != True: log_msg("Bank failed to start correctly!", 0) return result #handle the starting arguments: Startup.handle_args(ProgramState.STARTING_DIR, sys.argv[1:]) GlobalEvents.throw_event("startup") #if this is the first run, save all the settings files: if self.bbApp.isFirstRun: for app in [self.bbApp, self.btApp, self.torApp, self.ffApp]: if app: app.settings.save() self.coreSettings.save() #schedule update function: def do_update(): BWHistory.update_all() return True ProgramState.DO_UPDATES = True self.updateEvent = Scheduler.schedule_repeat( Globals.INTERVAL_BETWEEN_UPDATES, do_update) return result
def handle_args(startingDir, args): """ @param startingDir: the cwd of the process that these args came from @type startingDir: Unicode path @param args: the startup arguments (sys.argv) from some process, possibly us @type args: List of Strings""" (options, args) = Globals.PARSER.parse_args(args) GlobalEvents.throw_event("new_args", startingDir, options, args)
def apply_anon_mode(self, app): """Toggle which anonymity mode (how many hops) we are currently using, restart applications as necessary.""" if self.pathLength != app.pathLength: app.pathLength = self.pathLength if app.is_ready(): app.restart() self.save() GlobalEvents.throw_event("settings_changed")
def restart_for_update(self, newVersion): """Trigger an update after it has been downloaded""" if System.IS_WINDOWS: self.APPLY_UPDATE = True GlobalEvents.throw_event("quit_signal") else: #just prompt the user, since we cant really auto update in linux: GUIController.get().show_msgbox("Please close BitBlinder and run the following commands to update BitBlinder:\n\nsudo dpkg -P python-bitblinder\nsudo dpkg -i %s" % (Globals.UPDATE_FILE_NAME))
def _search_cb(self, widget, event=None): """launches the browser to do a google search for a torrent- it would be nice if this were moved to a reputable torrent site and we returned something within the gui itself""" url = "http://google.com/search?" searchTerms = self.searchEntry.get_text() + " torrent" url += urllib.urlencode({"q" : searchTerms}) log_msg("torrent search: %s" % (url), 3, "gui") GlobalEvents.throw_event("open_web_page_signal", url, not self.btApp.settings.useTor)
def _search_cb(self, widget, event=None): """launches the browser to do a google search for a torrent- it would be nice if this were moved to a reputable torrent site and we returned something within the gui itself""" url = "http://google.com/search?" searchTerms = self.searchEntry.get_text() + " torrent" url += urllib.urlencode({"q": searchTerms}) log_msg("torrent search: %s" % (url), 3, "gui") GlobalEvents.throw_event("open_web_page_signal", url, not self.btApp.settings.useTor)
def on_login_success(self, balance, authBlob, host, port, text): """Called when we successfully log in to the bank server, passed the response message @param balance: how many credits we have at the bank @type balance: int @param authBlob: the symmetric key to use for subsequent messages @type authBlob: str @param host: where to send subsequent messages @type host: str (ip addr) @param port: where to send subsequent messages @type port: int (port) @param text: a status code and message from the bank to possibly show the user. @type text: str""" if not self.startupDeferred: return log_msg("login was successful: \nServer says: %s" % (text), 4) if text: #If the code is non-zero, display the text code, text = Basic.read_byte(text) if code == 0: text = None self.loginInProgress = False #figure out the shared symmetric key from the bank (for use encrypting all later messages) self.secretKey = SymmetricKey.SymmetricKey(authBlob) self.host = host self.port = port if not self.isLoggedIn: self.isLoggedIn = True #determine some file names based on the username: self.ACOIN_FILE_NAME = os.path.join(Globals.USER_DATA_DIR, "acoins.txt") self.DEPOSITED_FILE_NAME = os.path.join(Globals.USER_DATA_DIR, "acoins_in_deposit.txt") #inform the gui that we've logged in: self._trigger_event("login_success", text) #load any coins we stored when we shut down previously: self.load_coins() log_msg("Bank login successful!", 3) #make sure we have enough ACoins: self.check_wallet_balance() #let other parts of the program react to the fact that we just logged in GlobalEvents.throw_event("login") #notify anyone waiting on the startup deferred: self.startupDeferred.callback(True) self.startupDeferred = None self._trigger_event("started") else: log_ex("already logged in", "The bank should not be started more than once")
def prompt_about_port(self, portNum, successFunc): pid = System.get_pid_from_port(portNum) if pid <= 0: successFunc() return programs = System.get_process_ids() programName = "None" for p in programs: if p[1] == pid: programName = p[0] break #this has to go in the console as it isn't seen otherwise self.shutdown_func = "" msg = "Port %s is taken by program %s (pid=%s). Please kill the program or otherwise free the port and restart BitBlinder."% (portNum, programName, pid) log_msg(msg, 0) atexit.register(self.print_wrapper, msg) GlobalEvents.throw_event("quit_signal")
def _update_ip(address, method): """Call this function when you learn about a new external IP address""" global _externalIP if not Twisted.is_local_ip(address): if not _externalIP: pass elif _externalIP != address: log_msg( "%s reported a different external IP than we already knew about: %s vs %s" % (method, Basic.clean(address), Basic.clean(_externalIP)), 3, ) else: return _externalIP = address GlobalEvents.throw_event("ip_update", address, method) else: log_msg("Learned about local address %s via %s, not very helpful..." % (Basic.clean(address), method), 4)
def _update_ip(address, method): """Call this function when you learn about a new external IP address""" global _externalIP if not Twisted.is_local_ip(address): if not _externalIP: pass elif _externalIP != address: log_msg( "%s reported a different external IP than we already knew about: %s vs %s" % (method, Basic.clean(address), Basic.clean(_externalIP)), 3) else: return _externalIP = address GlobalEvents.throw_event("ip_update", address, method) else: log_msg( "Learned about local address %s via %s, not very helpful..." % (Basic.clean(address), method), 4)
def prompt_about_port(self, portNum, successFunc): pid = System.get_pid_from_port(portNum) if pid <= 0: successFunc() return programs = System.get_process_ids() programName = "None" for p in programs: if p[1] == pid: programName = p[0] break #this has to go in the console as it isn't seen otherwise self.shutdown_func = "" msg = "Port %s is taken by program %s (pid=%s). Please kill the program or otherwise free the port and restart BitBlinder." % ( portNum, programName, pid) log_msg(msg, 0) atexit.register(self.print_wrapper, msg) GlobalEvents.throw_event("quit_signal")
def _shutdown(self, result): """Stop the main loop and cause the program to exit. This should ONLY be called after all Applications are shut down cleanly.""" Basic.validate_result(result, "MainLoop::_shutdown") #close the server that listens for new versions of the app to start up: StartupServer.stop() #remove scheduled events: if self.updateEvent and self.updateEvent.active(): self.updateEvent.cancel() ProgramState.DO_UPDATES = False self.updateEvent = None GlobalEvents.throw_event("shutdown") log_msg("Done with shutdown deferreds", 4) #close the main loop if ProgramState.USE_GTK: try: gtk.main_quit() except Exception, error: log_ex(error, "Couldn't kill the gtk main loop")
def _stop_done(self, result): Basic.validate_result(result, "BitTorrentWindow::_stop_done") if not BitBlinder.get().is_running(): GlobalEvents.throw_event("quit_signal") else: #are there any other apps using bitblinder? for app in BitBlinder.get().applications.values(): #if there is another app, dont bother shutting down everything if app.is_running() and app != Bank.get(): return #ok, check if there is a relay then if Tor.get().settings.beRelay: #then we should prompt about shutdown def callback(dialog, response): if response == gtk.RESPONSE_YES: self._do_quit() msgText = "BitBlinder is acting as a server and help others be anonymous, and earning you more credits!\n\nDo you also want to stop the server?" GUIController.get().show_preference_prompt(msgText, "Stop Relay?", callback, "promptAboutRelayQuit") else: #otherwise shutdown completely: self._do_quit()
def _stop_done(self, result): Basic.validate_result(result, "BitTorrentWindow::_stop_done") if not BitBlinder.get().is_running(): GlobalEvents.throw_event("quit_signal") else: #are there any other apps using bitblinder? for app in BitBlinder.get().applications.values(): #if there is another app, dont bother shutting down everything if app.is_running() and app != Bank.get(): return #ok, check if there is a relay then if Tor.get().settings.beRelay: #then we should prompt about shutdown def callback(dialog, response): if response == gtk.RESPONSE_YES: self._do_quit() msgText = "BitBlinder is acting as a server and help others be anonymous, and earning you more credits!\n\nDo you also want to stop the server?" GUIController.get().show_preference_prompt( msgText, "Stop Relay?", callback, "promptAboutRelayQuit") else: #otherwise shutdown completely: self._do_quit()
def _purchase_cb(self, widget=None): GlobalEvents.throw_event("open_web_page_signal", '%s/purchase/' % (ProgramState.Conf.BASE_HTTP), True) self._on_done()
def quit_done(self, result): GlobalEvents.throw_event("quit_signal")
def _quit_done(self, result): Basic.validate_result(result, "BitTorrentWindow::_quit_done") GlobalEvents.throw_event("quit_signal")
def show_website(self, widget): GlobalEvents.throw_event("open_web_page_signal", '%s/learn/about/' % (ProgramState.Conf.BASE_HTTP), True)
def show_forums(self, widget): GlobalEvents.throw_event("open_web_page_signal", '%s/forum/' % (ProgramState.Conf.BASE_HTTP), True)
def show_website(widget, event): #print widget widget.label.set_markup('<span underline="single" foreground="%s" size="%s">%s</span>' % ("purple", size, text)) GlobalEvents.throw_event("open_web_page_signal", widget.url, True)