def _create_applications(self): """Creates all application classes that the MainLoop coordinates. This does NOT start them- that's done later. WARNING: the gui assumes the apps exist! """ #create the Bank application: Bank.start() self.bankApp = Bank.get() #create the Tor application: Tor.start() self.torApp = Tor.get() #create the pseudo applications for InnomiNet BitBlinder.start(self.torApp, self.bankApp) self.bbApp = BitBlinder.get() #create the applications: BitTorrentClient.start(self.torApp) self.btApp = BitTorrentClient.get() self.bbApp.add_application(self.btApp) if System.IS_WINDOWS: FirefoxPortable.start(self.torApp) self.ffApp = FirefoxPortable.get() self.bbApp.add_application(self.ffApp) self.gui.on_applications_created(self.bankApp, self.torApp, self.bbApp, self.btApp, self.ffApp)
def getSelected(self): obj = None #get the selection sel = self.view.get_selection() #get the selected row model, iter = sel.get_selected() if iter: #get the "id" value for the row try: id = int(model.get_value(iter, 0)) except: #TODO: again, a really bad way of seeing that this is a Application treeRow return None isCircuit = int(model.get_value(iter, len(self.columnLabels))) #get the "path" of the row. This is a way of describing the position of #the row in the TreeView. If the path is one element long, the row is in #the top level of the tree. If it is two elements long, it is in the #second level, etc. IN this case, first level always means that it is a #circuit, so we can use that to decide whether to return the obj from #.streams or .circuits path = model.get_path(iter) #then this is a stream: if not isCircuit: obj = BitBlinder.get().get_stream(id) else: obj = BitBlinder.get().get_circuit(id) return obj
def country_changed_cb(self, combobox, args=None): country = self.countryCombo.get_active_text() if not country: country = None else: country = country.split(":")[0] BitBlinder.get().set_exit_country(country)
def create_box(self): #create each of the pages: self._mainBox = gtk.HBox() self.vbox.pack_start(self._mainBox, True, True, 0) BORDER_WIDTH = 10 def add_var(name, box, ignoreHBar=None): return self.add_variable(name, Tor.get().settings, Tor.get(), "", box, ignoreHBar) #general settings page: vbox = gtk.VBox() add_var("orPort", vbox) add_var("dirPort", vbox) add_var("dhtPort", vbox) vbox.set_border_width(BORDER_WIDTH) #windows settings, if necessary if System.IS_WINDOWS: startOnBootEntry = self.add_variable("startBitBlinderOnBoot", BitBlinder.get().settings, BitBlinder.get(), "", vbox) #NOTE: change the default to starting on bootup if we're a server now if not Tor.get().settings.wasRelay: startOnBootEntry.set_value(True) self.add_variable("halfOpenConnections", BitBlinder.get().settings, BitBlinder.get(), "", vbox) self._boxes.append(vbox) #exit traffic page: vbox = gtk.VBox() vbox.set_border_width(BORDER_WIDTH) exitTypeEntry = add_var("exitType", vbox, True) exitTypeEntry.set_value("Both") vbox.pack_start( GTKUtils.make_html_link( "Learn more about exit traffic", "%s/overview/" % (ProgramState.Conf.BASE_HTTP)), False, False, 2) self._boxes.append(vbox) #bandwidth page: vbox = gtk.VBox() vbox.set_border_width(BORDER_WIDTH) label = WrapLabel.WrapLabel("") label.set_markup( """<span size='large' weight='bold'>You should run BitBlinder in the background to accumulate credits. </span> """) vbox.pack_start(label, False, False, 0) # vbox.pack_start(gtk.HSeparator(), False, False, 0) add_var("monthlyCap", vbox) add_var("bwRate", vbox) add_var("bwSchedule", vbox) self._boxes.append(vbox) self._mainBox.set_size_request(600, -1) self.set_current_page()
def stream_status_event(self, event): """Callback from TorCtl for stream events @param event: the event structure from the Tor controller @type event: StreamEvent""" self.log_event(event, "STREAM") stream = BitBlinder.get().get_stream(event.strm_id) if not stream: #dont bother with streams that were started before we were: if event.status not in ("NEW", "NEWRESOLVE"): return BitBlinder.get().on_new_stream(event) else: #NOTE: stream_status_event is not called for the initial event: stream.stream_status_event(event)
def launch_test_upload(self, widget, event=None): test = None #get the selected item (either a Stream or Circuit) circ = self.getSelected() #if there was no selection or the selection was a stream, let BitBlinder pick the circuit if not circ or circ.__class__.__name__ != "Circuit" or not circ.is_open(): log_msg("Cannot upload through that %s" % (circ), 0) return class TestUploader(Int32StringReceiver): def connectionMade(self): self.bytesLeft = 2 * 1024 * 1024 self.transport.write(struct.pack("!I", self.bytesLeft)) self.sendEvent = Scheduler.schedule_repeat(0.1, self.send_more, 1024 * 10) def send_more(self, numBytes): self.transport.write("1"*numBytes) self.bytesLeft -= numBytes if self.bytesLeft <= 0: return False else: return True def stringReceived(self, data): log_msg("Upload hopefully done?") return factory = protocol.ClientFactory() factory.protocol = TestUploader #connect to the bank and send some trash: d = BitBlinder.get().launch_external_factory(Bank.get().host, Bank.get().port, factory, circ.handle_stream, "Test Upload")
def on_no_credits(self): bitBlinder = BitBlinder.get() showDialog = bitBlinder.is_running() and bitBlinder.settings.alwaysShowPovertyDialog if showDialog: if not self.povertyDialog: self.povertyDialog = PovertyDialog.PovertyDialog(self) self.povertyDialog.show()
def on_update(self): #update the client display if it's visible: if self.is_visible(): updatedApps = set() appInfos = BitBlinder.get().get_app_info() #update each socks applications: for appInfo in appInfos: (appName, numHops, dnrate, uprate, numCredits) = appInfo #insert a row for the app if it doesnt exist: if appName not in self.rows: iter = self.liststore.append(appInfo) self.rows[appName] = gtk.TreeRowReference(self.liststore, self.liststore.get_string_from_iter(iter)) #update the information in the row else: iter = self.liststore[self.rows[appName].get_path()].iter self.liststore.set(iter, self.attrIdx["rateUp"], uprate, self.attrIdx["rateDown"], dnrate, self.attrIdx["numHops"], numHops, self.attrIdx["numCredits"], numCredits) #note thate we've updated this row: updatedApps.add(appName) #remove all apps that were not updated: for appName in self.rows.keys(): if appName not in updatedApps: treeRow = self.rows[appName] iter = self.liststore[treeRow.get_path()].iter self.liststore.remove(iter) del self.rows[appName]
def try_new_circuit(self): """Try a new circuit when we are at the 'build a circuit' bootstrap phase. We build circuits like mad here, otherwise Tor takes forever to start up.""" for circ in self.startup_circuits: if circ.is_ready(): if not self.isReady: self.isReady = True self.torApp.on_ready() break if not self.isReady: path = self.torApp.make_path(1) if path: log_msg( "Trying to launch a circuit to %s" % (path[0].desc.nickname), 3) circ = BitBlinder.get().create_circuit(path, True) if circ: #since we dont actually care about this circuit, and it will be closed when we've started up circ.sendPayments = False self.startup_circuits.append(circ) else: log_msg( "No routers to try launching test circuits to during startup!", 1) return True else: #maybe kill any circuits we tried to launch: log_msg( "Closing %d startup circuits" % (len(self.startup_circuits)), 1) for c in self.startup_circuits: c.close() return False
def try_new_circuit(self): """Try a new circuit when we are at the 'build a circuit' bootstrap phase. We build circuits like mad here, otherwise Tor takes forever to start up.""" for circ in self.startup_circuits: if circ.is_ready(): if not self.isReady: self.isReady = True self.torApp.on_ready() break if not self.isReady: path = self.torApp.make_path(1) if path: log_msg("Trying to launch a circuit to %s" % (path[0].desc.nickname), 3) circ = BitBlinder.get().create_circuit(path, True) if circ: #since we dont actually care about this circuit, and it will be closed when we've started up circ.sendPayments = False self.startup_circuits.append(circ) else: log_msg("No routers to try launching test circuits to during startup!", 1) return True else: #maybe kill any circuits we tried to launch: log_msg("Closing %d startup circuits" % (len(self.startup_circuits)), 1) for c in self.startup_circuits: c.close() return False
def check_for_updates(self, success_cb=None, failure_cb=None): """Send out a request to the web server to check the current version information Returns True so that it is rescheduled to be called again later. success_cb=what to do when we've gotten the current version info failure_cb=what to do if we fail to get the current version info""" try: if not success_cb: success_cb = self.update_request_done url = self.baseURL + "current_version.txt" def on_failure(failure, instance, failure_cb=failure_cb): log_ex(failure, "Failed while downloading current version document", [ConnectionDone]) if failure_cb: failure_cb(failure, instance) #TODO: go through a circuit if the user wants to be stealthy: BitBlinder.http_download(url, None, success_cb, on_failure) except Exception, e: log_ex(e, "Failed while attempting to get update document")
def on_no_credits(self): bitBlinder = BitBlinder.get() showDialog = bitBlinder.is_running( ) and bitBlinder.settings.alwaysShowPovertyDialog if showDialog: if not self.povertyDialog: self.povertyDialog = PovertyDialog.PovertyDialog(self) self.povertyDialog.show()
def on_quit_signal(self): """Close all applications, then call shutdown.""" if not ProgramState.DONE: ProgramState.DONE = True if self.btApp and self.btApp.is_stopping(): self.btApp.force_stop() System.SHUTDOWN = True shutdownDeferred = BitBlinder.stop() shutdownDeferred.addCallback(self._shutdown) shutdownDeferred.addErrback(self._shutdown)
def start_connection(self, dns, id, encrypted=None): #This means that we are closed or shutting down if self.done: return #if self.connections == None: # return cons = len(self.connections) + self.incompletecounter if (self.paused or cons >= self.max_connections or id == self.my_id or not self.check_ip(ip=dns[0])): return #check if there are too many connections globally if not self.can_open_more_connections(): return if self.config['crypto_only']: if encrypted is None or encrypted: # fails on encrypted = 0 encrypted = True else: return for v in self.connections: if v is None: continue if id and v.id == id: return True ip = v.get_ip() if self.config['security'] and ip != 'unknown' and ip == dns[0]: return #log_msg("BT Protocol Began", 3, "btconn") self.incompletecounter += 1 log_msg( "Starting BT connection: %s %s" % (len(self.connections), self.incompletecounter), 3, "btconn") if self.config['use_socks']: BitBlinder.get().launch_external_protocol( dns[0], dns[1], OutgoingBTProtocol(self, id, encrypted, True), self.handle_stream, self.connect_failed, id) else: d = protocol.ClientCreator(Globals.reactor, OutgoingBTProtocol, self, id, encrypted, False).connectTCP(dns[0], dns[1], 30) d.addCallback(self.direct_connect_succeeded) d.addErrback(self.connect_failed) return
def create_box(self): #create each of the pages: self._mainBox = gtk.HBox() self.vbox.pack_start(self._mainBox, True, True, 0) BORDER_WIDTH = 10 def add_var(name, box, ignoreHBar=None): return self.add_variable(name, Tor.get().settings, Tor.get(), "", box, ignoreHBar) #general settings page: vbox = gtk.VBox() add_var("orPort", vbox) add_var("dirPort", vbox) add_var("dhtPort", vbox) vbox.set_border_width(BORDER_WIDTH) #windows settings, if necessary if System.IS_WINDOWS: startOnBootEntry = self.add_variable("startBitBlinderOnBoot", BitBlinder.get().settings, BitBlinder.get(), "", vbox) #NOTE: change the default to starting on bootup if we're a server now if not Tor.get().settings.wasRelay: startOnBootEntry.set_value(True) self.add_variable("halfOpenConnections", BitBlinder.get().settings, BitBlinder.get(), "", vbox) self._boxes.append(vbox) #exit traffic page: vbox = gtk.VBox() vbox.set_border_width(BORDER_WIDTH) exitTypeEntry = add_var("exitType", vbox, True) exitTypeEntry.set_value("Both") vbox.pack_start(GTKUtils.make_html_link("Learn more about exit traffic", "%s/overview/" % (ProgramState.Conf.BASE_HTTP)), False, False, 2) self._boxes.append(vbox) #bandwidth page: vbox = gtk.VBox() vbox.set_border_width(BORDER_WIDTH) label = WrapLabel.WrapLabel("") label.set_markup("""<span size='large' weight='bold'>You should run BitBlinder in the background to accumulate credits. </span> """) vbox.pack_start(label, False, False, 0) # vbox.pack_start(gtk.HSeparator(), False, False, 0) add_var("monthlyCap", vbox) add_var("bwRate", vbox) add_var("bwSchedule", vbox) self._boxes.append(vbox) self._mainBox.set_size_request(600, -1) self.set_current_page()
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 launch_test_download(self, widget, event=None): test = None #get the selected item (either a Stream or Circuit) circ = self.getSelected() #if there was no selection or the selection was a stream, let BitBlinder pick the circuit if not circ or circ.__class__.__name__ != "Circuit": #TODO: actually use the test URL/port here... circ = BitBlinder.get().find_or_build_best_circuit("", 80) #make sure there is a circuit: if not circ: log_msg("Failed to find an appropriate circuit", 1) return #make sure we dont try to attach to a close circuit if not circ.is_open(): log_msg("Circuit %d is closed" % circ.id, 2) return def page_done(data, httpDownloadInstance): self.end_time = time.time() log_msg("Test downloaded " + str(len(data)) + " bytes", 2) test = BitBlinder.http_download(Globals.TEST_URL, circ, page_done)
def start_connection(self, dns, id, encrypted = None): #This means that we are closed or shutting down if self.done: return #if self.connections == None: # return cons = len(self.connections) + self.incompletecounter if ( self.paused or cons >= self.max_connections or id == self.my_id or not self.check_ip(ip=dns[0]) ): return #check if there are too many connections globally if not self.can_open_more_connections(): return if self.config['crypto_only']: if encrypted is None or encrypted: # fails on encrypted = 0 encrypted = True else: return for v in self.connections: if v is None: continue if id and v.id == id: return True ip = v.get_ip() if self.config['security'] and ip != 'unknown' and ip == dns[0]: return #log_msg("BT Protocol Began", 3, "btconn") self.incompletecounter += 1 log_msg("Starting BT connection: %s %s" % (len(self.connections), self.incompletecounter), 3, "btconn") if self.config['use_socks']: BitBlinder.get().launch_external_protocol(dns[0], dns[1], OutgoingBTProtocol(self, id, encrypted, True), self.handle_stream, self.connect_failed, id) else: d = protocol.ClientCreator(Globals.reactor, OutgoingBTProtocol, self, id, encrypted, False).connectTCP(dns[0], dns[1], 30) d.addCallback(self.direct_connect_succeeded) d.addErrback(self.connect_failed) return
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 launch_circuit(self, widget, event=None): path = [] len = 0 for i in range(0, 3): str = self.routerCombos[i].get_active_text() if not str or str == "": pass else: len = i + 1 if len == 0: BitBlinder.get().build_circuit("", 80) return for i in range(0, 3): str = self.routerCombos[i].get_active_text() r = None if not str or str == "": r = self.torApp.make_path(1)[0] else: hexId = str.split("~")[1] r = self.torApp.get_relay(hexId) path.append(r) if i + 1 >= len: break circ = BitBlinder.get().create_circuit(path)
def token_level_event(self, event): """Called each second for each Circuit. @param event: the event structure from the Tor controller @type event: TokenLevelEvent""" self.log_event(event, "TOKEN_LEVELS") circ = BitBlinder.get().get_circuit(event.circ_id) if circ: if circ.is_done(): return readTraffic = Globals.BYTES_PER_CELL * (circ.lastPayedReads - (event.reads - event.reads_added)) writeTraffic = Globals.BYTES_PER_CELL * (circ.lastPayedWrites - (event.writes - event.writes_added)) circ.lastPayedReads = event.reads circ.lastPayedWrites = event.writes circ.handle_token_response(event.reads, event.writes) circ.handle_bw_event(readTraffic, writeTraffic)
def circ_status_event(self, event): """Callback from TorCtl for circuit events @param event: the event structure from the Tor controller @type event: StreamEvent""" self.log_event(event, "CIRC") circ = BitBlinder.get().get_circuit(event.circ_id) #NOTE: IMPORTANT: Circuits should NOT recieve circ_status_event calls for #the status event with which they were created. if not circ: #create Circuits if they dont exist already, and we're observing internal #circuits: if Circuit.OBSERVE_INTERNAL: circ = Circuit.Circuit(event, self.torApp, event.circ_id) else: circ.circ_status_event(event)
def launch_circuit(self, widget, event=None): path = [] len = 0 for i in range(0,3): str = self.routerCombos[i].get_active_text() if not str or str == "": pass else: len = i+1 if len == 0: BitBlinder.get().build_circuit("", 80) return for i in range(0,3): str = self.routerCombos[i].get_active_text() r = None if not str or str == "": r = self.torApp.make_path(1)[0] else: hexId = str.split("~")[1] r = self.torApp.get_relay(hexId) path.append(r) if i+1 >= len: break circ = BitBlinder.get().create_circuit(path)
def download_update(self, newVersionData): """Download the latest version of InnomiNet from the web server newVersion=the version to download""" self.newVersion = newVersionData[0] self.trueHash = newVersionData[1] self.updateString = newVersionData[2] if System.IS_WINDOWS: #if we're not already doing the update: if not self.downloadingUpdate: self.downloadingUpdate = True #baseURL += "BitBlinderUpdate-%s-%s.exe" % (Globals.VERSION, self.newVersion) fileName = "BitBlinderInstaller-%s.exe" % (self.newVersion) url = self.baseURL + fileName #TODO: go through a circuit if the user wants to be stealthy: BitBlinder.http_download(url, None, self.request_done, self.request_failed, progressCB=self.progressCB, fileName=Globals.UPDATE_FILE_NAME+".download") GUIController.get().show_msgbox("BitBlinder found a new version (%s)!\n\nDownloading update now... (you can choose whether to restart later)" % (self.newVersion)) else: #url = self.baseURL + "python-bitblinder_%s_%s.deb" % (self.newVersion, platform.machine()) url = "%s/download/" % (ProgramState.Conf.BASE_HTTP) if ProgramState.USE_GTK: link = GTKUtils.make_html_link(url, url) else: link = url GUIController.get().show_msgbox("A new linux package is available! Changes:\n\n%s\n\nGo download and install it from:" % (self.updateString), title="Update Available", link=link)
def token_level_event(self, event): """Called each second for each Circuit. @param event: the event structure from the Tor controller @type event: TokenLevelEvent""" self.log_event(event, "TOKEN_LEVELS") circ = BitBlinder.get().get_circuit(event.circ_id) if circ: if circ.is_done(): return readTraffic = Globals.BYTES_PER_CELL * ( circ.lastPayedReads - (event.reads - event.reads_added)) writeTraffic = Globals.BYTES_PER_CELL * ( circ.lastPayedWrites - (event.writes - event.writes_added)) circ.lastPayedReads = event.reads circ.lastPayedWrites = event.writes circ.handle_token_response(event.reads, event.writes) circ.handle_bw_event(readTraffic, writeTraffic)
def launch_test_upload(self, widget, event=None): test = None #get the selected item (either a Stream or Circuit) circ = self.getSelected() #if there was no selection or the selection was a stream, let BitBlinder pick the circuit if not circ or circ.__class__.__name__ != "Circuit" or not circ.is_open( ): log_msg("Cannot upload through that %s" % (circ), 0) return class TestUploader(Int32StringReceiver): def connectionMade(self): self.bytesLeft = 2 * 1024 * 1024 self.transport.write(struct.pack("!I", self.bytesLeft)) self.sendEvent = Scheduler.schedule_repeat( 0.1, self.send_more, 1024 * 10) def send_more(self, numBytes): self.transport.write("1" * numBytes) self.bytesLeft -= numBytes if self.bytesLeft <= 0: return False else: return True def stringReceived(self, data): log_msg("Upload hopefully done?") return factory = protocol.ClientFactory() factory.protocol = TestUploader #connect to the bank and send some trash: d = BitBlinder.get().launch_external_factory(Bank.get().host, Bank.get().port, factory, circ.handle_stream, "Test Upload")
def _do_quit(self): quitDeferred = BitBlinder.get().stop() quitDeferred.addCallback(self._quit_done) quitDeferred.addErrback(self._quit_done)
def _on_done(self): BitBlinder.get().settings.alwaysShowPovertyDialog = self.alwaysShow.get_active() BitBlinder.get().settings.save() self.window.hide()
def __init__(self): bbApp = BitBlinder.get() self.bbApp = bbApp self.torApp = bbApp.torApp self.catch_event("tor_ready") self.catch_event("tor_done") self.catch_event("new_relay") ClientUtil.add_updater(self) #create the view and store for all the data columns: #TODO: make display text prettier (transition to MB as appropriate, etc) self.mdl = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, int, str, str, "gboolean") modelfilter = self.mdl.filter_new() self.visColumn = 10 modelfilter.set_visible_column(self.visColumn) self.view = gtk.TreeView(modelfilter) self.columnLabels = [ "ID", "Status", "Path", "BW (down)", "Reason", "Age", "Total (Down)" ] #add each of the columns for i in range(0, len(self.columnLabels)): name = self.columnLabels[i] colId = i #make column column = gtk.TreeViewColumn(name) #basic string renderer for the data in the column column.cell = gtk.CellRendererText() #add the renderer to the column... idk if you can add more than one column.pack_start(column.cell, True) #add the column to the treeview self.view.append_column(column) ##TODO: this gave an exception last time for some reason ##this acts as a macro to set a bunch of properties that make this column sortable #column.set_sort_column_id(colId) #tell the column where to get it's string data, and the data for colors column.set_attributes(column.cell, text=colId, background=len(self.columnLabels) + 1, foreground=len(self.columnLabels) + 2) #set properties to make the column interact intuitively. column.set_properties(reorderable=True, expand=True, clickable=True, resizable=True) hbox = gtk.HBox() self.showCircuits = False self.showStreams = False button = gtk.CheckButton("Show closed Streams:") button.connect("toggled", self.toggle_cb, "streams") hbox.pack_start(button) button = gtk.CheckButton("Show closed Circuits:") button.connect("toggled", self.toggle_cb, "circuits") hbox.pack_start(button) self.vbox = gtk.VBox() #make scrollwindow because the circuit list gets really long self.scrolled_window = gtk.ScrolledWindow() self.scrolled_window.set_border_width(10) self.scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) #self.scrolled_window.set_size_request(500, 500) self.scrolled_window.add_with_viewport(self.view) self.scrolled_window.show() self.comboRow = gtk.HButtonBox() self.buttonRow = gtk.HButtonBox() # self.testRow = gtk.HBox() self.vbox.pack_start(hbox, False) self.vbox.pack_start(self.scrolled_window) self.vbox.pack_start(self.comboRow, False) self.vbox.pack_start(self.buttonRow, False) # self.vbox.pack_start(self.testRow, False) self.testStreams = [] self.objects = set() self.routerCombos = [] for i in range(0, 3): combo = gtk.combo_box_new_text() self.routerCombos.append(combo) combo.set_size_request(100, -1) self.comboRow.pack_start(combo) self.countryCombo = gtk.combo_box_new_text() self.countryCombo.append_text("") self.countryCombo.set_size_request(150, -1) self.comboRow.pack_start(self.countryCombo) self.countryCombo.connect("changed", self.country_changed_cb) b = gtk.Button("Launch Circuit") self.buttonRow.pack_start(b) b.connect('clicked', self.launch_circuit) b = gtk.Button("Download") self.buttonRow.pack_start(b) b.connect('clicked', self.launch_test_download) b = gtk.Button("Upload") self.buttonRow.pack_start(b) b.connect('clicked', self.launch_test_upload) b = gtk.Button("PAR Test") self.buttonRow.pack_start(b) b.connect('clicked', self.launch_par_test) b = gtk.Button("DHT") self.buttonRow.pack_start(b) b.connect('clicked', self.dht_cb) b = gtk.Button("Inspect") self.buttonRow.pack_start(b) b.connect('clicked', self.inspect_cb) b = gtk.Button("Kill Selected") self.buttonRow.pack_start(b) b.connect('clicked', self.kill_selected) self.vbox.show() self.comboRow.show() self.buttonRow.show() #these are used by GTK Controller to easily add the component to the main window self.label = gtk.Label("Circuit List") self.container = self.vbox
def __init__(self): bbApp = BitBlinder.get() self.bbApp = bbApp self.torApp = bbApp.torApp self.catch_event("tor_ready") self.catch_event("tor_done") self.catch_event("new_relay") ClientUtil.add_updater(self) #create the view and store for all the data columns: #TODO: make display text prettier (transition to MB as appropriate, etc) self.mdl = gtk.TreeStore( gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, int, str, str, "gboolean" ) modelfilter = self.mdl.filter_new() self.visColumn = 10 modelfilter.set_visible_column(self.visColumn) self.view = gtk.TreeView( modelfilter ) self.columnLabels = ["ID", "Status", "Path", "BW (down)", "Reason", "Age", "Total (Down)"] #add each of the columns for i in range(0,len(self.columnLabels)): name = self.columnLabels[i] colId = i #make column column = gtk.TreeViewColumn(name) #basic string renderer for the data in the column column.cell = gtk.CellRendererText() #add the renderer to the column... idk if you can add more than one column.pack_start(column.cell, True) #add the column to the treeview self.view.append_column(column) ##TODO: this gave an exception last time for some reason ##this acts as a macro to set a bunch of properties that make this column sortable #column.set_sort_column_id(colId) #tell the column where to get it's string data, and the data for colors column.set_attributes(column.cell, text=colId, background=len(self.columnLabels)+1, foreground=len(self.columnLabels)+2) #set properties to make the column interact intuitively. column.set_properties(reorderable=True, expand=True, clickable=True, resizable=True) hbox = gtk.HBox() self.showCircuits = False self.showStreams = False button = gtk.CheckButton("Show closed Streams:") button.connect("toggled", self.toggle_cb, "streams") hbox.pack_start(button) button = gtk.CheckButton("Show closed Circuits:") button.connect("toggled", self.toggle_cb, "circuits") hbox.pack_start(button) self.vbox = gtk.VBox() #make scrollwindow because the circuit list gets really long self.scrolled_window = gtk.ScrolledWindow() self.scrolled_window.set_border_width(10) self.scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) #self.scrolled_window.set_size_request(500, 500) self.scrolled_window.add_with_viewport(self.view) self.scrolled_window.show() self.comboRow = gtk.HButtonBox() self.buttonRow = gtk.HButtonBox() # self.testRow = gtk.HBox() self.vbox.pack_start(hbox, False) self.vbox.pack_start(self.scrolled_window) self.vbox.pack_start(self.comboRow, False) self.vbox.pack_start(self.buttonRow, False) # self.vbox.pack_start(self.testRow, False) self.testStreams = [] self.objects = set() self.routerCombos = [] for i in range(0,3): combo = gtk.combo_box_new_text() self.routerCombos.append(combo) combo.set_size_request(100, -1) self.comboRow.pack_start(combo) self.countryCombo = gtk.combo_box_new_text() self.countryCombo.append_text("") self.countryCombo.set_size_request(150, -1) self.comboRow.pack_start(self.countryCombo) self.countryCombo.connect("changed", self.country_changed_cb) b = gtk.Button("Launch Circuit") self.buttonRow.pack_start(b) b.connect('clicked', self.launch_circuit) b = gtk.Button("Download") self.buttonRow.pack_start(b) b.connect('clicked', self.launch_test_download) b = gtk.Button("Upload") self.buttonRow.pack_start(b) b.connect('clicked', self.launch_test_upload) b = gtk.Button("PAR Test") self.buttonRow.pack_start(b) b.connect('clicked', self.launch_par_test) b = gtk.Button("DHT") self.buttonRow.pack_start(b) b.connect('clicked', self.dht_cb) b = gtk.Button("Inspect") self.buttonRow.pack_start(b) b.connect('clicked', self.inspect_cb) b = gtk.Button("Kill Selected") self.buttonRow.pack_start(b) b.connect('clicked', self.kill_selected) self.vbox.show() self.comboRow.show() self.buttonRow.show() #these are used by GTK Controller to easily add the component to the main window self.label = gtk.Label("Circuit List") self.container = self.vbox