[tor-commits] [research-web/master] petsymposium is https now
commit 643acc70f5c42b8df6c32183fa1a1eaade09ab58 Author: Roger DingledineDate: Mon Apr 18 21:50:54 2016 -0400 petsymposium is https now --- htdocs/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/index.html b/htdocs/index.html index 4f77d2a..50921b7 100644 --- a/htdocs/index.html +++ b/htdocs/index.html @@ -112,7 +112,7 @@ really important. So let us know, and we'll work something out. If you're interested in anonymity research, you must make it to the -http://petsymposium.org/;>Privacy Enhancing Technologies +https://petsymposium.org/;>Privacy Enhancing Technologies Symposium. Everybody who's anybody in the anonymity research world will be there. Stipends are generally available for people whose presence will benefit the community. ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [check/master] Add some translations
commit abca67d60674e9b93f6be6621cc86b0ef07218aa Author: Arlo BreaultDate: Mon Apr 18 14:18:52 2016 -0700 Add some translations --- utils.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/utils.go b/utils.go index 0872c15..4d438d2 100644 --- a/utils.go +++ b/utils.go @@ -171,12 +171,14 @@ func GetLocaleList(base string) map[string]string { "hr_HR": "Hrvatski jezik (Croatia)", "hu": "Magyar", "id": "Bahasa Indonesia", + "is": "Ãslenska", "it": "Italiano", "ja": "æ¥æ¬èª", "km": "ááá", "kn": "à²à²¨à³à²¨à²¡", "ko": "íêµì´", "ko_KR": "íêµì´ (South Korea)", + "lb": "Lëtzebuergesch", "lo": "ລາວ", "lv": "LatvieÅ¡u valoda", "mk": "македонÑки Ñазик", @@ -208,6 +210,7 @@ func GetLocaleList(base string) map[string]string { "tr": "Türkçe", "uk": "ÑкÑаÑнÑÑка мова", "zh_CN": "ä¸æç®ä½", + "zh_HK": "ä¸æç¹é«", "zh_TW": "ä¸æç¹é«", } ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [nyx/master] Test overall header panel rendering
commit bcd498a464172ada4e760de20b6a7caf5d5c44a9 Author: Damian JohnsonDate: Mon Apr 18 13:19:38 2016 -0700 Test overall header panel rendering --- nyx/panel/header.py | 2 +- test/__init__.py | 2 +- test/panel/header.py | 62 3 files changed, 64 insertions(+), 2 deletions(-) diff --git a/nyx/panel/header.py b/nyx/panel/header.py index a9712b4..d470ba1 100644 --- a/nyx/panel/header.py +++ b/nyx/panel/header.py @@ -175,7 +175,7 @@ class HeaderPanel(nyx.panel.DaemonPanel): _draw_fingerprint_and_fd_usage(subwindow, 0, 3, left_width, vals) _draw_flags(subwindow, 0, 4, vals.flags) -_draw_status(subwindow, 0, subwindow.height - 1, self.is_paused(), self._message, *self._message_attr) +_draw_status(subwindow, 0, self.get_height() - 1, self.is_paused(), self._message, *self._message_attr) def reset_listener(self, controller, event_type, _): self._update() diff --git a/test/__init__.py b/test/__init__.py index 178b79d..3730254 100644 --- a/test/__init__.py +++ b/test/__init__.py @@ -71,7 +71,7 @@ def render(func, *args, **kwargs): func_args = inspect.getargspec(func).args -if func_args and func_args[0] == 'subwindow': +if func_args[:1] == ['subwindow'] or func_args[:2] == ['self', 'subwindow']: def _draw(subwindow): return func(subwindow, *args, **kwargs) diff --git a/test/panel/header.py b/test/panel/header.py index 58f700c..62d54af 100644 --- a/test/panel/header.py +++ b/test/panel/header.py @@ -16,8 +16,70 @@ import test from test import require_curses from mock import patch, Mock +EXPECTED_PANEL = """ +nyx - odin (Linux 3.5.0-54-generic)Tor 0.2.8.1-alpha-dev +Unnamed - 174.21.17.28:7000, Dir Port: 7001, Control Port (cookie): 7002 +cpu: 12.3% tor, 5.7% nyx mem: 11 MB (2.1%) pid: 765 +fingerprint: 1A94D1A794FCB2F8B6CBC179EF8FDD4008A98D3B +flags: Running, Exit + +page 2 / 4 - m: menu, p: pause, h: page help, q: quit +""".strip() + + +def test_sampling(): + return nyx.panel.header.Sampling( +retrieved = 1234.5, +is_connected = True, +connection_time = 2345.6, +last_heartbeat = 3456.7, + +fingerprint = '1A94D1A794FCB2F8B6CBC179EF8FDD4008A98D3B', +nickname = 'Unnamed', +newnym_wait = None, +exit_policy = stem.exit_policy.ExitPolicy('reject *:*'), +flags = ['Running', 'Exit'], + +version = '0.2.8.1-alpha-dev', +version_status = 'unrecommended', + +address = '174.21.17.28', +or_port = '7000', +dir_port = '7001', +control_port = '7002', +socket_path = None, +is_relay = True, + +auth_type = 'cookie', +pid = '765', +start_time = 4567.8, +fd_limit = 100, +fd_used = 40, + +nyx_total_cpu_time = 100, +tor_cpu = '12.3', +nyx_cpu = '5.7', +memory = '11 MB', +memory_percent = '2.1', + +hostname = 'odin', +platform = 'Linux 3.5.0-54-generic', + ) + class TestHeader(unittest.TestCase): + @require_curses + @patch('nyx.controller.get_controller') + @patch('nyx.panel.header.tor_controller') + @patch('nyx.panel.header.Sampling.create') + def test_rendering_panel(self, sampling_mock, tor_controller_mock, nyx_controller_mock): +nyx_controller_mock().get_page.return_value = 1 +nyx_controller_mock().get_page_count.return_value = 4 +sampling_mock.return_value = test_sampling() + +panel = nyx.panel.header.HeaderPanel() +self.assertEqual(EXPECTED_PANEL, test.render(panel.draw).content) + @patch('nyx.panel.header.tor_controller') @patch('nyx.tracker.get_resource_tracker') @patch('time.time', Mock(return_value = 1234.5)) ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [nyx/master] Fix nyx event names in tests
commit c6a21afa3a6d182e6f16f8860c61a4490b5685ac Author: Damian JohnsonDate: Mon Apr 18 12:52:20 2016 -0700 Fix nyx event names in tests Oops, changed what our warning and error runlevels were but didn't update the tests. --- test/arguments.py | 12 ++-- test/log/condense_runlevels.py | 4 ++-- test/popups.py | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/test/arguments.py b/test/arguments.py index d27281c..76c6d38 100644 --- a/test/arguments.py +++ b/test/arguments.py @@ -68,7 +68,7 @@ class TestArgumentParsing(unittest.TestCase): class TestExpandEvents(unittest.TestCase): def test_examples(self): self.assertEqual(set(['INFO', 'NOTICE', 'UNKNOWN', 'TRANSPORT_LAUNCHED']), expand_events('inUt')) -self.assertEqual(set(['NOTICE', 'WARN', 'ERR', 'NYX_WARN', 'NYX_ERR']), expand_events('N4')) +self.assertEqual(set(['NOTICE', 'WARN', 'ERR', 'NYX_WARNING', 'NYX_ERROR']), expand_events('N4')) self.assertEqual(set(), expand_events('cfX')) def test_runlevel_expansion(self): @@ -78,11 +78,11 @@ class TestExpandEvents(unittest.TestCase): self.assertEqual(set(['WARN', 'ERR']), expand_events('W')) self.assertEqual(set(['ERR']), expand_events('E')) -self.assertEqual(set(['NYX_DEBUG', 'NYX_INFO', 'NYX_NOTICE', 'NYX_WARN', 'NYX_ERR']), expand_events('1')) -self.assertEqual(set(['NYX_INFO', 'NYX_NOTICE', 'NYX_WARN', 'NYX_ERR']), expand_events('2')) -self.assertEqual(set(['NYX_NOTICE', 'NYX_WARN', 'NYX_ERR']), expand_events('3')) -self.assertEqual(set(['NYX_WARN', 'NYX_ERR']), expand_events('4')) -self.assertEqual(set(['NYX_ERR']), expand_events('5')) +self.assertEqual(set(['NYX_DEBUG', 'NYX_INFO', 'NYX_NOTICE', 'NYX_WARNING', 'NYX_ERROR']), expand_events('1')) +self.assertEqual(set(['NYX_INFO', 'NYX_NOTICE', 'NYX_WARNING', 'NYX_ERROR']), expand_events('2')) +self.assertEqual(set(['NYX_NOTICE', 'NYX_WARNING', 'NYX_ERROR']), expand_events('3')) +self.assertEqual(set(['NYX_WARNING', 'NYX_ERROR']), expand_events('4')) +self.assertEqual(set(['NYX_ERROR']), expand_events('5')) def test_short_circuit_options(self): # Check that the 'A' and 'X' options short circuit normal parsing, diff --git a/test/log/condense_runlevels.py b/test/log/condense_runlevels.py index f7c831c..5c06d92 100644 --- a/test/log/condense_runlevels.py +++ b/test/log/condense_runlevels.py @@ -9,5 +9,5 @@ class TestCondenseRunlevels(unittest.TestCase): self.assertEqual(['BW'], condense_runlevels('BW')) self.assertEqual(['DEBUG', 'NOTICE', 'ERR'], condense_runlevels('DEBUG', 'NOTICE', 'ERR')) self.assertEqual(['DEBUG-NOTICE', 'NYX DEBUG-INFO'], condense_runlevels('DEBUG', 'NYX_DEBUG', 'INFO', 'NYX_INFO', 'NOTICE')) -self.assertEqual(['TOR/NYX NOTICE-ERR'], condense_runlevels('NOTICE', 'WARN', 'ERR', 'NYX_NOTICE', 'NYX_WARN', 'NYX_ERR')) -self.assertEqual(['DEBUG', 'TOR/NYX NOTICE-ERR', 'BW'], condense_runlevels('DEBUG', 'NOTICE', 'WARN', 'ERR', 'NYX_NOTICE', 'NYX_WARN', 'NYX_ERR', 'BW')) +self.assertEqual(['TOR/NYX NOTICE-ERR'], condense_runlevels('NOTICE', 'WARN', 'ERR', 'NYX_NOTICE', 'NYX_WARNING', 'NYX_ERROR')) +self.assertEqual(['DEBUG', 'TOR/NYX NOTICE-ERR', 'BW'], condense_runlevels('DEBUG', 'NOTICE', 'WARN', 'ERR', 'NYX_NOTICE', 'NYX_WARNING', 'NYX_ERROR', 'BW')) diff --git a/test/popups.py b/test/popups.py index f38cb45..d782b96 100644 --- a/test/popups.py +++ b/test/popups.py @@ -313,7 +313,7 @@ class TestPopups(unittest.TestCase): def test_select_event_types_with_input(self): rendered = test.render(nyx.popups.select_event_types) self.assertEqual(EXPECTED_EVENT_SELECTOR, rendered.content) -self.assertEqual(set(['NYX_INFO', 'ERR', 'WARN', 'BW', 'NYX_ERR', 'NYX_WARN', 'NYX_NOTICE']), rendered.return_value) +self.assertEqual(set(['NYX_INFO', 'ERR', 'WARN', 'BW', 'NYX_ERROR', 'NYX_WARNING', 'NYX_NOTICE']), rendered.return_value) @require_curses @patch('nyx.popups._top', Mock(return_value = 0)) ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [nyx/master] Fix nyx error logging
commit 26ded909760b5e143e8a6bf061b8fa9b1d44ef39 Author: Damian JohnsonDate: Mon Apr 18 11:33:43 2016 -0700 Fix nyx error logging Log messages at our error level weren't being displayed. This is because we logged them as 'NYX_ERROR' but expected 'NYX_ERR'. We were attempted to name our runlevels after tor but on reflection lets not - tor's names suck. Showing our actual runlevel names which are... * WARN => WARNING * ERR => ERROR --- nyx/arguments.py| 10 -- nyx/log.py | 14 +++--- nyx/panel/log.py| 3 --- nyx/settings/attributes.cfg | 4 ++-- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/nyx/arguments.py b/nyx/arguments.py index e70278b..ad8ea4a 100644 --- a/nyx/arguments.py +++ b/nyx/arguments.py @@ -10,6 +10,7 @@ import getopt import os import nyx +import nyx.log import stem.util.connection @@ -215,12 +216,9 @@ def expand_events(flags): expanded_events, invalid_flags = set(), '' - tor_runlevels = ['DEBUG', 'INFO', 'NOTICE', 'WARN', 'ERR'] - nyx_runlevels = ['NYX_' + runlevel for runlevel in tor_runlevels] - for flag in flags: if flag == 'A': - return set(list(TOR_EVENT_TYPES) + nyx_runlevels + ['UNKNOWN']) + return set(list(TOR_EVENT_TYPES) + nyx.log.NYX_RUNLEVELS + ['UNKNOWN']) elif flag == 'X': return set() elif flag in 'DINWE12345': @@ -238,9 +236,9 @@ def expand_events(flags): runlevel_index = 4 if flag in 'DINWE': -runlevels = tor_runlevels[runlevel_index:] +runlevels = nyx.log.TOR_RUNLEVELS[runlevel_index:] elif flag in '12345': -runlevels = nyx_runlevels[runlevel_index:] +runlevels = nyx.log.NYX_RUNLEVELS[runlevel_index:] expanded_events.update(set(runlevels)) elif flag == 'U': diff --git a/nyx/log.py b/nyx/log.py index ec09c3f..2a60a9e 100644 --- a/nyx/log.py +++ b/nyx/log.py @@ -61,6 +61,7 @@ except ImportError: from stem.util.lru_cache import lru_cache TOR_RUNLEVELS = ['DEBUG', 'INFO', 'NOTICE', 'WARN', 'ERR'] +NYX_RUNLEVELS = ['NYX_DEBUG', 'NYX_INFO', 'NYX_NOTICE', 'NYX_WARNING', 'NYX_ERROR'] TIMEZONE_OFFSET = time.altzone if time.localtime()[8] else time.timezone @@ -133,9 +134,16 @@ def condense_runlevels(*events): tor_runlevels.append(r) events.remove(r) -if 'NYX_%s' % r in events: +if r == 'WARN': + nyx_runlevel = 'NYX_WARNING' +elif r == 'ERR': + nyx_runlevel = 'NYX_ERROR' +else: + nyx_runlevel = 'NYX_%s' % r + +if nyx_runlevel in events: nyx_runlevels.append(r) - events.remove('NYX_%s' % r) + events.remove(nyx_runlevel) tor_ranges = ranges(tor_runlevels) nyx_ranges = ranges(nyx_runlevels) @@ -180,7 +188,7 @@ def listen_for_events(listener, events): # accounts for runlevel naming difference tor_events = events.intersection(set(nyx.arguments.TOR_EVENT_TYPES.values())) - nyx_events = events.intersection(set(['NYX_%s' % runlevel for runlevel in TOR_RUNLEVELS])) + nyx_events = events.intersection(set(NYX_RUNLEVELS)) # adds events unrecognized by nyx if we're listening to the 'UNKNOWN' type diff --git a/nyx/panel/log.py b/nyx/panel/log.py index 3e8932d..278c633 100644 --- a/nyx/panel/log.py +++ b/nyx/panel/log.py @@ -378,9 +378,6 @@ class LogPanel(nyx.panel.DaemonPanel): self._register_event(nyx.log.LogEntry(event.arrived_at, event.type, msg)) def _register_nyx_event(self, record): -if record.levelname == 'WARNING': - record.levelname = 'WARN' - self._register_event(nyx.log.LogEntry(int(record.created), 'NYX_%s' % record.levelname, record.msg)) def _register_event(self, event): diff --git a/nyx/settings/attributes.cfg b/nyx/settings/attributes.cfg index fcc78f3..37e8ebc 100644 --- a/nyx/settings/attributes.cfg +++ b/nyx/settings/attributes.cfg @@ -48,8 +48,8 @@ attr.log_color ERR => Red attr.log_color NYX_DEBUG => Magenta attr.log_color NYX_INFO => Blue attr.log_color NYX_NOTICE => Green -attr.log_color NYX_WARN => Yellow -attr.log_color NYX_ERR => Red +attr.log_color NYX_WARNING => Yellow +attr.log_color NYX_ERROR => Red attr.log_color CIRC => Yellow attr.log_color BW => Cyan ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [nyx/master] Finish and test header panel
commit c8b4852149e90786196d35a930ce18226f0587b7 Merge: 60a5765 bcd498a Author: Damian JohnsonDate: Mon Apr 18 13:22:21 2016 -0700 Finish and test header panel On our first pass we left a few todo comments. Finishing these off and adding tests for panel rendering. Not perfect, but good enough as a template for the rest of our panels. nyx/arguments.py | 10 +- nyx/controller.py | 18 +- nyx/curses.py | 66 + nyx/log.py | 14 +- nyx/panel/__init__.py | 200 - nyx/panel/connection.py| 47 +--- nyx/panel/graph.py | 2 +- nyx/panel/header.py| 621 +++-- nyx/panel/log.py | 58 +--- nyx/panel/torrc.py | 2 +- nyx/settings/attributes.cfg| 4 +- nyx/tracker.py | 5 +- nyxrc.sample | 4 - test/__init__.py | 22 +- test/arguments.py | 12 +- test/log/condense_runlevels.py | 4 +- test/panel/__init__.py | 7 + test/panel/header.py | 349 +++ test/popups.py | 2 +- 19 files changed, 838 insertions(+), 609 deletions(-) ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [nyx/master] Move panel threading to subclass
commit e0adea1ffcccf1cde046dfad698da7ce6f19b51d Author: Damian JohnsonDate: Sun Apr 17 18:02:56 2016 -0700 Move panel threading to subclass Three of our panels are also threads, performing actions at a set rate. All three have identical boilerplate so moving this to a DaemonPanel sublass of Panel. This rejiggers how the log panel works. The work it did to sleep minimal amounts of time was both silly and pointless. --- nyx/panel/__init__.py | 46 -- nyx/panel/connection.py | 47 ++- nyx/panel/header.py | 37 ++ nyx/panel/log.py| 53 + nyxrc.sample| 4 5 files changed, 57 insertions(+), 130 deletions(-) diff --git a/nyx/panel/__init__.py b/nyx/panel/__init__.py index 028ba73..86e64ac 100644 --- a/nyx/panel/__init__.py +++ b/nyx/panel/__init__.py @@ -6,11 +6,12 @@ Panels consisting the nyx interface. """ import collections -import inspect -import time import curses import curses.ascii import curses.textpad +import inspect +import threading +import time import nyx.curses import stem.util.log @@ -710,3 +711,44 @@ class Panel(object): self.addch(top, left + width - 1, curses.ACS_URCORNER, *attributes) self.addch(top + height - 1, left, curses.ACS_LLCORNER, *attributes) self.addch(top + height - 1, left + width - 1, curses.ACS_LRCORNER, *attributes) + + +class DaemonPanel(Panel, threading.Thread): + def __init__(self, name, top = 0, left = 0, height = -1, width = -1, update_rate = 10): +Panel.__init__(self, name, top, left, height, width) +threading.Thread.__init__(self) +self.setDaemon(True) + +self._pause_condition = threading.Condition() +self._halt = False # terminates thread if true +self._update_rate = update_rate + + def _update(self): +pass + + def run(self): +""" +Performs our _update() action at the given rate. +""" + +last_ran = -1 + +while not self._halt: + if self.is_paused() or (time.time() - last_ran) < self._update_rate: +with self._pause_condition: + if not self._halt: +self._pause_condition.wait(0.2) + +continue # done waiting, try again + + self._update() + last_ran = time.time() + + def stop(self): +""" +Halts further resolutions and terminates the thread. +""" + +with self._pause_condition: + self._halt = True + self._pause_condition.notifyAll() diff --git a/nyx/panel/connection.py b/nyx/panel/connection.py index e7e80f5..b75376d 100644 --- a/nyx/panel/connection.py +++ b/nyx/panel/connection.py @@ -10,7 +10,6 @@ import time import collections import curses import itertools -import threading import nyx.curses import nyx.panel @@ -256,16 +255,14 @@ class CircuitEntry(Entry): return False -class ConnectionPanel(nyx.panel.Panel, threading.Thread): +class ConnectionPanel(nyx.panel.DaemonPanel): """ Listing of connections tor is making, with information correlated against the current consensus and other data sources. """ def __init__(self): -nyx.panel.Panel.__init__(self, 'connections') -threading.Thread.__init__(self) -self.setDaemon(True) +nyx.panel.DaemonPanel.__init__(self, 'connections', update_rate = UPDATE_RATE) self._scroller = nyx.curses.CursorScroller() self._entries = []# last fetched display entries @@ -274,9 +271,6 @@ class ConnectionPanel(nyx.panel.Panel, threading.Thread): self._last_resource_fetch = -1 # timestamp of the last ConnectionResolver results used -self._pause_condition = threading.Condition() -self._halt = False # terminates thread if true - # Tracks exiting port and client country statistics self._client_locale_usage = {} @@ -317,34 +311,6 @@ class ConnectionPanel(nyx.panel.Panel, threading.Thread): self._sort_order = results self._entries = sorted(self._entries, key = lambda entry: [entry.sort_value(attr) for attr in self._sort_order]) - def run(self): -""" -Keeps connections listing updated, checking for new entries at a set rate. -""" - -last_ran = -1 - -while not self._halt: - if self.is_paused() or not tor_controller().is_alive() or (time.time() - last_ran) < UPDATE_RATE: -with self._pause_condition: - if not self._halt: -self._pause_condition.wait(0.2) - -continue # done waiting, try again - - self._update() - self.redraw(True) - - # TODO: The following is needed to show results *but* causes curses to - # flicker. For our plans on this see... - # - # https://trac.torproject.org/projects/tor/ticket/18547#comment:1 - - # if last_ran == -1: - # nyx.tracker.get_consensus_tracker().update(tor_controller().get_network_statuses([]))
[tor-commits] [nyx/master] Initialize header to a proper width
commit 95febabba28fac36d48d7f4e0c58a661de37ebe5 Author: Damian JohnsonDate: Sun Apr 17 13:01:50 2016 -0700 Initialize header to a proper width Using the actual screen size when initializing rather than a hardcoded value. This should prevent things from jumping around at startup on smaller monitors. --- nyx/panel/header.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nyx/panel/header.py b/nyx/panel/header.py index 115bd3b..164929b 100644 --- a/nyx/panel/header.py +++ b/nyx/panel/header.py @@ -18,6 +18,7 @@ import stem.util.str_tools import stem.util.system import nyx.controller +import nyx.curses import nyx.panel import nyx.popups import nyx.tracker @@ -50,7 +51,7 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread): self._vals = Sampling.create() -self._last_width = 100 +self._last_width = nyx.curses.screen_size()[0] self._pause_condition = threading.Condition() self._halt = False # terminates thread if true self._reported_inactive = False ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [nyx/master] Always redraw header when updating
commit 2b67c9f4d97b8d232ec3b09f0dde9794cc5c18df Author: Damian JohnsonDate: Sat Apr 16 13:28:31 2016 -0700 Always redraw header when updating When we update our stats we always want to redraw. Kinda obvious, and little reason not to. In practice we were *never* calling forced redraws in this method because the previous_height check was always true (since we fetched the 'previous' at the same time as the 'current'). --- nyx/panel/header.py | 10 +- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/nyx/panel/header.py b/nyx/panel/header.py index 4e4f922..84b4b38 100644 --- a/nyx/panel/header.py +++ b/nyx/panel/header.py @@ -239,7 +239,6 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread): log.notice('Tor control port closed') def _update(self): -previous_height = self.get_height() self._vals = Sampling.create(self._vals) if self._vals.fd_used and self._vals.fd_limit != -1: @@ -261,14 +260,7 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread): self._reported_inactive = False log.notice('Relay resumed') -if previous_height != self.get_height(): - # We're toggling between being a relay and client, causing the height - # of this panel to change. Redraw all content so we don't get - # overlapping content. - - nyx.controller.get_controller().redraw() -else: - self.redraw(True) # just need to redraw ourselves +self.redraw(True) class Sampling(object): ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [nyx/master] Restore ability to reconnect to tor
commit 520200cd8d8d29181795b17ed6b22acd59af2138 Author: Damian JohnsonDate: Mon Apr 11 09:42:40 2016 -0700 Restore ability to reconnect to tor While rewriting I disabled our ability to reconnect when tor has been restarted. Turns out reason it wasn't working was because we needed a thread safe 'connect and reauthenticate' method. Lack of thread safety was causing our other controller activity to disrupt re-authentication. All seems to be well now. --- nyx/panel/header.py | 14 ++ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/nyx/panel/header.py b/nyx/panel/header.py index 01922ec..998a20d 100644 --- a/nyx/panel/header.py +++ b/nyx/panel/header.py @@ -31,6 +31,7 @@ UPDATE_RATE = 5 # rate in seconds at which we refresh CONFIG = conf.config_dict('nyx', { 'attr.flag_colors': {}, 'attr.version_status_colors': {}, + 'tor.chroot': '', }) @@ -137,22 +138,11 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread): if self._vals.is_connected: return - # TODO: This is borked. Not quite sure why but our attempt to call - # PROTOCOLINFO fails with a socket error, followed by completely freezing - # nyx. This is exposing two bugs... - # - # * This should be working. That's a stem issue. - # * Our interface shouldn't be locking up. That's an nyx issue. - - return - controller = tor_controller() try: -controller.connect() - try: - controller.authenticate() # TODO: should account for our chroot + controller.reconnect(chroot_path = CONFIG['tor.chroot']) except stem.connection.MissingPassword: password = self.input_prompt('Controller Password: ') ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [nyx/master] Drop most Panel constructor arguments
commit 5199380f4aeda3b763bc3077c713cb0f51846249 Author: Damian JohnsonDate: Sun Apr 17 18:10:51 2016 -0700 Drop most Panel constructor arguments The location and dimension arguments were only around for popups. Now that those use the new nyx.curses functions no need to keep them around. --- nyx/panel/__init__.py | 14 +++--- nyx/panel/connection.py | 2 +- nyx/panel/header.py | 2 +- nyx/panel/log.py| 2 +- nyx/panel/torrc.py | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/nyx/panel/__init__.py b/nyx/panel/__init__.py index 86e64ac..39b8f85 100644 --- a/nyx/panel/__init__.py +++ b/nyx/panel/__init__.py @@ -166,7 +166,7 @@ class Panel(object): redraw(). """ - def __init__(self, name, top = 0, left = 0, height = -1, width = -1): + def __init__(self, name): """ Creates a durable wrapper for a curses subwindow in the given parent. @@ -188,10 +188,10 @@ class Panel(object): self.paused = False self.pause_time = -1 -self.top = top -self.left = left -self.height = height -self.width = width +self.top = 0 +self.left = 0 +self.height = -1 +self.width = -1 # The panel's subwindow instance. This is made available to implementors # via their draw method and shouldn't be accessed directly. @@ -714,8 +714,8 @@ class Panel(object): class DaemonPanel(Panel, threading.Thread): - def __init__(self, name, top = 0, left = 0, height = -1, width = -1, update_rate = 10): -Panel.__init__(self, name, top, left, height, width) + def __init__(self, name, update_rate): +Panel.__init__(self, name) threading.Thread.__init__(self) self.setDaemon(True) diff --git a/nyx/panel/connection.py b/nyx/panel/connection.py index b75376d..863be22 100644 --- a/nyx/panel/connection.py +++ b/nyx/panel/connection.py @@ -262,7 +262,7 @@ class ConnectionPanel(nyx.panel.DaemonPanel): """ def __init__(self): -nyx.panel.DaemonPanel.__init__(self, 'connections', update_rate = UPDATE_RATE) +nyx.panel.DaemonPanel.__init__(self, 'connections', UPDATE_RATE) self._scroller = nyx.curses.CursorScroller() self._entries = []# last fetched display entries diff --git a/nyx/panel/header.py b/nyx/panel/header.py index df139f0..2441704 100644 --- a/nyx/panel/header.py +++ b/nyx/panel/header.py @@ -44,7 +44,7 @@ class HeaderPanel(nyx.panel.DaemonPanel): """ def __init__(self): -nyx.panel.DaemonPanel.__init__(self, 'header', update_rate = UPDATE_RATE) +nyx.panel.DaemonPanel.__init__(self, 'header', UPDATE_RATE) self._vals = Sampling.create() self._last_width = nyx.curses.screen_size()[0] diff --git a/nyx/panel/log.py b/nyx/panel/log.py index 1e1e87e..3e8932d 100644 --- a/nyx/panel/log.py +++ b/nyx/panel/log.py @@ -66,7 +66,7 @@ class LogPanel(nyx.panel.DaemonPanel): """ def __init__(self): -nyx.panel.DaemonPanel.__init__(self, 'log', update_rate = UPDATE_RATE) +nyx.panel.DaemonPanel.__init__(self, 'log', UPDATE_RATE) logged_events = nyx.arguments.expand_events(CONFIG['startup.events']) self._event_log = nyx.log.LogGroup(CONFIG['cache.log_panel.size'], group_by_day = True) diff --git a/nyx/panel/torrc.py b/nyx/panel/torrc.py index 2943807..b279ea0 100644 --- a/nyx/panel/torrc.py +++ b/nyx/panel/torrc.py @@ -24,7 +24,7 @@ class TorrcPanel(panel.Panel): """ def __init__(self): -panel.Panel.__init__(self, 'torrc', 0) +panel.Panel.__init__(self, 'torrc') self._scroller = nyx.curses.Scroller() self._show_line_numbers = True # shows left aligned line numbers ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [nyx/master] Show notice when we're attempting to reconnect to tor
commit 29a4653b380f25b70293339c6587949c645a950a Author: Damian JohnsonDate: Mon Apr 18 11:42:01 2016 -0700 Show notice when we're attempting to reconnect to tor Tor takes a while before it accepts control connections. If you tell nyx to reconnect right after restarting tor it can hang for upward of thirty seconds. Showing a message to at least give a visual que that this is going on. --- nyx/panel/header.py | 1 + 1 file changed, 1 insertion(+) diff --git a/nyx/panel/header.py b/nyx/panel/header.py index 6551800..897ffbc 100644 --- a/nyx/panel/header.py +++ b/nyx/panel/header.py @@ -137,6 +137,7 @@ class HeaderPanel(nyx.panel.DaemonPanel): return controller = tor_controller() + self.show_message('Reconnecting...', HIGHLIGHT) try: try: ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [nyx/master] Draw helper for status message
commit 68cb4ab6a854d41aab575c5f0ac934aa263b6444 Author: Damian JohnsonDate: Sun Apr 17 12:52:52 2016 -0700 Draw helper for status message Just a small helper so this can be uniform with the rest. --- nyx/panel/header.py | 24 test/panel/header.py | 10 ++ 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/nyx/panel/header.py b/nyx/panel/header.py index 84b4b38..115bd3b 100644 --- a/nyx/panel/header.py +++ b/nyx/panel/header.py @@ -56,7 +56,7 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread): self._reported_inactive = False self._message = None -self._message_attr = None +self._message_attr = [] tor_controller().add_status_listener(self.reset_listener) @@ -197,13 +197,7 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread): _draw_fingerprint_and_fd_usage(subwindow, 0, 3, left_width, vals) _draw_flags(subwindow, 0, 4, vals.flags) -if self._message: - subwindow.addstr(0, subwindow.height - 1, self._message, *self._message_attr) -elif not self.is_paused(): - controller = nyx.controller.get_controller() - subwindow.addstr(0, subwindow.height - 1, 'page %i / %i - m: menu, p: pause, h: page help, q: quit' % (controller.get_page() + 1, controller.get_page_count())) -else: - subwindow.addstr(0, subwindow.height - 1, 'Paused', HIGHLIGHT) +_draw_status(subwindow, 0, subwindow.height - 1, self.is_paused(), self._message, *self._message_attr) def run(self): """ @@ -544,3 +538,17 @@ def _draw_newnym_option(subwindow, x, y, newnym_wait): else: plural = 's' if newnym_wait > 1 else '' subwindow.addstr(x, y, 'building circuits, available again in %i second%s' % (newnym_wait, plural)) + + +def _draw_status(subwindow, x, y, is_paused, message, *attr): + """ + Provides general usage information or a custom message. + """ + + if message: +subwindow.addstr(x, y, message, *attr) + elif not is_paused: +controller = nyx.controller.get_controller() +subwindow.addstr(x, y, 'page %i / %i - m: menu, p: pause, h: page help, q: quit' % (controller.get_page() + 1, controller.get_page_count())) + else: +subwindow.addstr(x, y, 'Paused', HIGHLIGHT) diff --git a/test/panel/header.py b/test/panel/header.py index e601f00..58f700c 100644 --- a/test/panel/header.py +++ b/test/panel/header.py @@ -275,3 +275,13 @@ class TestHeader(unittest.TestCase): self.assertEqual("press 'n' for a new identity", test.render(nyx.panel.header._draw_newnym_option, 0, 0, 0).content) self.assertEqual('building circuits, available again in 1 second', test.render(nyx.panel.header._draw_newnym_option, 0, 0, 1).content) self.assertEqual('building circuits, available again in 5 seconds', test.render(nyx.panel.header._draw_newnym_option, 0, 0, 5).content) + + @require_curses + @patch('nyx.controller.get_controller') + def test_draw_status(self, nyx_controller_mock): +nyx_controller_mock().get_page.return_value = 1 +nyx_controller_mock().get_page_count.return_value = 4 + +self.assertEqual('page 2 / 4 - m: menu, p: pause, h: page help, q: quit', test.render(nyx.panel.header._draw_status, 0, 0, False, None).content) +self.assertEqual('Paused', test.render(nyx.panel.header._draw_status, 0, 0, True, None).content) +self.assertEqual('pepperjack is wonderful!', test.render(nyx.panel.header._draw_status, 0, 0, False, 'pepperjack is wonderful!').content) ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [nyx/master] Crashed if event popup not provided with any input
commit 80be479323ab50ec1d764a26bc2cecfd9c236c1b Author: Damian JohnsonDate: Sun Apr 17 13:10:32 2016 -0700 Crashed if event popup not provided with any input Didn't account for the None value when this dialog is canceled... File "./run_nyx", line 8, in nyx.main() File "/home/atagar/Desktop/nyx/nyx/__init__.py", line 60, in main nyx.starter.main() File "/home/atagar/Desktop/nyx/stem/util/conf.py", line 289, in wrapped return func(*args, config = config, **kwargs) File "/home/atagar/Desktop/nyx/nyx/starter.py", line 89, in main nyx.curses.start(nyx.controller.start_nyx, transparent_background = True, cursor = False) File "/home/atagar/Desktop/nyx/nyx/curses.py", line 190, in start curses.wrapper(_wrapper) File "/usr/lib/python2.7/curses/wrapper.py", line 43, in wrapper return func(stdscr, *args, **kwds) File "/home/atagar/Desktop/nyx/nyx/curses.py", line 188, in _wrapper function() File "/home/atagar/Desktop/nyx/nyx/controller.py", line 370, in start_nyx keybinding.handle(key) File "/home/atagar/Desktop/nyx/nyx/panel/__init__.py", line 81, in handle self._action() File "/home/atagar/Desktop/nyx/nyx/panel/log.py", line 147, in show_event_selection_prompt self._event_types = nyx.log.listen_for_events(self._register_tor_event, event_types) File "/home/atagar/Desktop/nyx/nyx/log.py", line 178, in listen_for_events events = set(events) # drops duplicates TypeError: 'NoneType' object is not iterable --- nyx/panel/log.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nyx/panel/log.py b/nyx/panel/log.py index a18b2ce..cc8183b 100644 --- a/nyx/panel/log.py +++ b/nyx/panel/log.py @@ -143,7 +143,7 @@ class LogPanel(nyx.panel.Panel, threading.Thread): event_types = nyx.popups.select_event_types() -if event_types != self._event_types: +if event_types and event_types != self._event_types: self._event_types = nyx.log.listen_for_events(self._register_tor_event, event_types) self.redraw(True) ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [nyx/master] Move input_prompt() to controller
commit 2d2e0c4435dda692c97a895ece690cf6b11f04db Author: Damian JohnsonDate: Mon Apr 18 12:02:07 2016 -0700 Move input_prompt() to controller The controller already proxies this, so might as well move the implementation over too. It's tiny. Also dropping a duplicate redraw() call. --- nyx/controller.py | 18 +- nyx/panel/header.py | 20 +--- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/nyx/controller.py b/nyx/controller.py index 3336837..1957770 100644 --- a/nyx/controller.py +++ b/nyx/controller.py @@ -66,7 +66,23 @@ def show_message(message = None, *attr, **kwargs): def input_prompt(msg, initial_value = ''): - return get_controller().header_panel().input_prompt(msg, initial_value) + """ + Prompts the user for input. + + :param str message: prompt for user input + :param str initial_value: initial value of the prompt + + :returns: **str** with the user input, this is **None** if the prompt is +canceled + """ + + header_panel = get_controller().header_panel() + + header_panel.show_message(msg) + user_input = nyx.curses.str_input(len(msg), header_panel.get_height() - 1, initial_value) + header_panel.show_message() + + return user_input class Controller(object): diff --git a/nyx/panel/header.py b/nyx/panel/header.py index 897ffbc..a9712b4 100644 --- a/nyx/panel/header.py +++ b/nyx/panel/header.py @@ -77,24 +77,6 @@ class HeaderPanel(nyx.panel.DaemonPanel): self.show_message() # clear override return user_input - def input_prompt(self, message, initial_value = ''): -""" -Prompts the user for input. - -:param str message: prompt for user input -:param str initial_value: initial value of the prompt - -:returns: **str** with the user input, this is **None** if the prompt is - canceled -""" - -self.show_message(message) -self.redraw(True) -user_input = nyx.curses.str_input(len(message), self.get_height() - 1, initial_value) -self.show_message() - -return user_input - def is_wide(self): """ True if we should show two columns of information, False otherwise. @@ -143,7 +125,7 @@ class HeaderPanel(nyx.panel.DaemonPanel): try: controller.reconnect(chroot_path = CONFIG['tor.chroot']) except stem.connection.MissingPassword: - password = self.input_prompt('Controller Password: ') + password = nyx.controller.input_prompt('Controller Password: ') if password: controller.authenticate(password) ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [nyx/master] Test _draw_flags()
commit 7c41f64f8e98f35614f5ab3cbeb0da837cd528af Author: Damian JohnsonDate: Sun Apr 10 12:16:53 2016 -0700 Test _draw_flags() --- nyx/panel/header.py | 43 ++- test/panel/header.py | 6 ++ 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/nyx/panel/header.py b/nyx/panel/header.py index da0ba7f..00d4794 100644 --- a/nyx/panel/header.py +++ b/nyx/panel/header.py @@ -194,7 +194,7 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread): if vals.is_relay: _draw_fingerprint_and_fd_usage(subwindow, left_width, 1, right_width, vals) -self._draw_flags(subwindow, 0, 2, left_width, vals) +_draw_flags(subwindow, 0, 2, vals.flags) self._draw_exit_policy(subwindow, left_width, 2, right_width, vals) elif vals.is_connected: self._draw_newnym_option(subwindow, left_width, 1, right_width, vals) @@ -203,7 +203,7 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread): if vals.is_relay: _draw_fingerprint_and_fd_usage(subwindow, 0, 3, left_width, vals) -self._draw_flags(subwindow, 0, 4, left_width, vals) +_draw_flags(subwindow, 0, 4, vals.flags) if self._message: subwindow.addstr(0, subwindow.height - 1, self._message, *self._message_attr) @@ -213,25 +213,6 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread): else: subwindow.addstr(0, subwindow.height - 1, 'Paused', HIGHLIGHT) - def _draw_flags(self, subwindow, x, y, width, vals): -""" -Presents flags held by our relay... - - flags: Running, Valid -""" - -x = subwindow.addstr(x, y, 'flags: ') - -if vals.flags: - for i, flag in enumerate(vals.flags): -flag_color = CONFIG['attr.flag_colors'].get(flag, WHITE) -x = subwindow.addstr(x, y, flag, flag_color, BOLD) - -if i < len(vals.flags) - 1: - x = subwindow.addstr(x, y, ', ') -else: - subwindow.addstr(x, y, 'none', CYAN, BOLD) - def _draw_exit_policy(self, subwindow, x, y, width, vals): """ Presents our exit policy... @@ -562,3 +543,23 @@ def _draw_fingerprint_and_fd_usage(subwindow, x, y, width, vals): x = subwindow.addstr(x, y, vals.format(': {fd_used} / {fd_limit} (')) x = subwindow.addstr(x, y, '%i%%' % fd_percent, *percentage_format) subwindow.addstr(x, y, ')') + + +def _draw_flags(subwindow, x, y, flags): + """ + Presents flags held by our relay... + +flags: Running, Valid + """ + + x = subwindow.addstr(x, y, 'flags: ') + + if flags: +for i, flag in enumerate(flags): + flag_color = CONFIG['attr.flag_colors'].get(flag, WHITE) + x = subwindow.addstr(x, y, flag, flag_color, BOLD) + + if i < len(flags) - 1: +x = subwindow.addstr(x, y, ', ') + else: +subwindow.addstr(x, y, 'none', CYAN, BOLD) diff --git a/test/panel/header.py b/test/panel/header.py index 0d80f0f..39982e0 100644 --- a/test/panel/header.py +++ b/test/panel/header.py @@ -156,3 +156,9 @@ class TestHeader(unittest.TestCase): ) self.assertEqual(expected, test.render(nyx.panel.header._draw_fingerprint_and_fd_usage, 0, 0, 80, vals).content) + + @require_curses + def test_draw_flags(self): +self.assertEqual('flags: none', test.render(nyx.panel.header._draw_flags, 0, 0, []).content) +self.assertEqual('flags: Guard', test.render(nyx.panel.header._draw_flags, 0, 0, ['Guard']).content) +self.assertEqual('flags: Running, Exit', test.render(nyx.panel.header._draw_flags, 0, 0, ['Running', 'Exit']).content) ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [nyx/master] Test _draw_newnym_option()
commit 385b4f1a958665a3bd0da2176c0b64ff571fbc52 Author: Damian JohnsonDate: Sun Apr 10 13:04:41 2016 -0700 Test _draw_newnym_option() --- nyx/panel/header.py | 27 ++- test/panel/header.py | 6 ++ 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/nyx/panel/header.py b/nyx/panel/header.py index 96b8383..9288db9 100644 --- a/nyx/panel/header.py +++ b/nyx/panel/header.py @@ -197,7 +197,7 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread): _draw_flags(subwindow, 0, 2, vals.flags) _draw_exit_policy(subwindow, left_width, 2, vals.exit_policy) elif vals.is_connected: -self._draw_newnym_option(subwindow, left_width, 1, right_width, vals) +_draw_newnym_option(subwindow, left_width, 1, vals.newnym_wait) else: _draw_resource_usage(subwindow, 0, 2, left_width, vals, pause_time) @@ -213,18 +213,6 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread): else: subwindow.addstr(0, subwindow.height - 1, 'Paused', HIGHLIGHT) - def _draw_newnym_option(self, subwindow, x, y, width, vals): -""" -Provide a notice for requiesting a new identity, and time until it's next -available if in the process of building circuits. -""" - -if vals.newnym_wait == 0: - subwindow.addstr(x, y, "press 'n' for a new identity") -else: - plural = 's' if vals.newnym_wait > 1 else '' - subwindow.addstr(x, y, 'building circuits, available again in %i second%s' % (vals.newnym_wait, plural)) - def run(self): """ Keeps stats updated, checking for new information at a set rate. @@ -564,3 +552,16 @@ def _draw_exit_policy(subwindow, x, y, exit_policy): x = subwindow.addstr(x, y, ', ') subwindow.addstr(x, y, '', CYAN, BOLD) + + +def _draw_newnym_option(subwindow, x, y, newnym_wait): + """ + Provide a notice for requiesting a new identity, and time until it's next + available if in the process of building circuits. + """ + + if newnym_wait == 0: +subwindow.addstr(x, y, "press 'n' for a new identity") + else: +plural = 's' if newnym_wait > 1 else '' +subwindow.addstr(x, y, 'building circuits, available again in %i second%s' % (newnym_wait, plural)) diff --git a/test/panel/header.py b/test/panel/header.py index 9794644..209ce8b 100644 --- a/test/panel/header.py +++ b/test/panel/header.py @@ -168,3 +168,9 @@ class TestHeader(unittest.TestCase): def test_draw_exit_policy(self): self.assertEqual('exit policy: reject *:*', test.render(nyx.panel.header._draw_exit_policy, 0, 0, stem.exit_policy.ExitPolicy('reject *:*')).content) self.assertEqual('exit policy: accept *:80, accept *:443, reject *:*', test.render(nyx.panel.header._draw_exit_policy, 0, 0, stem.exit_policy.ExitPolicy('accept *:80', 'accept *:443', 'reject *:*')).content) + + @require_curses + def test_draw_newnym_option(self): +self.assertEqual("press 'n' for a new identity", test.render(nyx.panel.header._draw_newnym_option, 0, 0, 0).content) +self.assertEqual('building circuits, available again in 1 second', test.render(nyx.panel.header._draw_newnym_option, 0, 0, 1).content) +self.assertEqual('building circuits, available again in 5 seconds', test.render(nyx.panel.header._draw_newnym_option, 0, 0, 5).content) ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [nyx/master] Curses str_input() function for getting input
commit da970b76736b836360da85de1b609d584990d002 Author: Damian JohnsonDate: Sun Apr 17 19:50:31 2016 -0700 Curses str_input() function for getting input Replacing our Panel's getstr() method with simplified version in our curses module. This drops workarounds to work with python 2.5 (meh) and formatted initial text (unused). --- nyx/curses.py | 66 nyx/panel/__init__.py | 139 -- nyx/panel/header.py | 4 +- 3 files changed, 68 insertions(+), 141 deletions(-) diff --git a/nyx/curses.py b/nyx/curses.py index ebe5eef..f357443 100644 --- a/nyx/curses.py +++ b/nyx/curses.py @@ -14,6 +14,7 @@ if we want Windows support in the future too. start - initializes curses with the given function raw_screen - provides direct access to the curses screen key_input - get keypress by user + str_input - text field where user can input a string curses_attr - curses encoded text attribute screen_size - provides the dimensions of our screen screenshot - dump of the present on-screen content @@ -82,6 +83,8 @@ from __future__ import absolute_import import collections import curses +import curses.ascii +import curses.textpad import threading import stem.util.conf @@ -239,6 +242,69 @@ def key_input(input_timeout = None): return KeyInput(CURSES_SCREEN.getch()) +def str_input(x, y, initial_text = ''): + """ + Provides a text field where the user can input a string, blocking until + they've done so and returning the result. If the user presses escape then + this terminates and provides back **None**. + + This blanks any content within the space that the input field is rendered + (otherwise stray characters would be interpreted as part of the initial + input). + + :param int x: horizontal location + :param int y: vertical location + :param str initial_text: initial input of the field + + :returns: **str** with the user input or **None** if the prompt is caneled + """ + + def handle_key(textbox, key): +y, x = textbox.win.getyx() + +if key == 27: + return curses.ascii.BEL # user pressed esc +elif key == curses.KEY_HOME: + textbox.win.move(y, 0) +elif key in (curses.KEY_END, curses.KEY_RIGHT): + msg_length = len(textbox.gather()) + textbox.win.move(y, x) # reverts cursor movement during gather call + + if key == curses.KEY_END and msg_length > 0 and x < msg_length - 1: +textbox.win.move(y, msg_length - 1) # if we're in the content then move to the end + elif key == curses.KEY_RIGHT and x < msg_length - 1: +textbox.win.move(y, x + 1) # only move cursor if there's content after it +elif key == 410: + # if we're resizing the display during text entry then cancel it + # (otherwise the input field is filled with nonprintable characters) + + return curses.ascii.BEL +else: + return key + + with CURSES_LOCK: +try: + curses.curs_set(1) # show cursor +except curses.error: + pass + +width = screen_size().width - x + +curses_subwindow = CURSES_SCREEN.subwin(1, width, y, x) +curses_subwindow.erase() +curses_subwindow.addstr(0, 0, initial_text[:width - 1]) + +textbox = curses.textpad.Textbox(curses_subwindow, insert_mode = True) +user_input = textbox.edit(lambda key: handle_key(textbox, key)).strip() + +try: + curses.curs_set(0) # hide cursor +except curses.error: + pass + +return None if textbox.lastcmd == curses.ascii.BEL else user_input + + def curses_attr(*attributes): """ Provides encoding for the given curses text attributes. diff --git a/nyx/panel/__init__.py b/nyx/panel/__init__.py index 39b8f85..1f5143d 100644 --- a/nyx/panel/__init__.py +++ b/nyx/panel/__init__.py @@ -7,8 +7,6 @@ Panels consisting the nyx interface. import collections import curses -import curses.ascii -import curses.textpad import inspect import threading import time @@ -19,8 +17,6 @@ import stem.util.log from nyx.curses import HIGHLIGHT from stem.util import conf, str_tools -PASS = -1 - __all__ = [ 'config', 'connection', @@ -82,76 +78,6 @@ class KeyHandler(collections.namedtuple('Help', ['key', 'description', 'current' self._action() -class BasicValidator(object): - """ - Interceptor for keystrokes given to a textbox, doing the following: - - quits by setting the input to curses.ascii.BEL when escape is pressed - - stops the cursor at the end of the box's content when pressing the right -arrow - - home and end keys move to the start/end of the line - """ - - def validate(self, key, textbox): -""" -Processes the given key input for the textbox. This may modify the -textbox's content, cursor position, etc depending on the functionality -of the validator. This returns the key that the textbox should interpret, -PASS if this validator doesn't want to take any
[tor-commits] [nyx/master] Test _draw_platform_section()
commit 619cb2186fe67414c4ce1e49e7eb07821bdf24c8 Author: Damian JohnsonDate: Sat Apr 9 21:48:37 2016 -0700 Test _draw_platform_section() First test for our header panel. This requires our render() method to provide a draw context but other than that straight forward. I'm not a fan of the new _sampling() function. I'll change that when we add tests for get_sampling(). --- nyx/panel/header.py| 91 ++ test/__init__.py | 17 -- test/panel/__init__.py | 7 test/panel/header.py | 47 ++ 4 files changed, 116 insertions(+), 46 deletions(-) diff --git a/nyx/panel/header.py b/nyx/panel/header.py index 8efbf8e..f49efe1 100644 --- a/nyx/panel/header.py +++ b/nyx/panel/header.py @@ -45,7 +45,7 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread): threading.Thread.__init__(self) self.setDaemon(True) -self._vals = get_sampling() +self._vals = _get_sampling() self._last_width = 100 self._pause_condition = threading.Condition() @@ -181,7 +181,7 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread): left_width = max(subwindow.width / 2, 77) if is_wide else subwindow.width right_width = subwindow.width - left_width -self._draw_platform_section(subwindow, 0, 0, left_width, vals) +_draw_platform_section(subwindow, 0, 0, left_width, vals) if vals.is_connected: self._draw_ports_section(subwindow, 0, 1, left_width, vals) @@ -212,35 +212,6 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread): else: subwindow.addstr(0, subwindow.height - 1, 'Paused', HIGHLIGHT) - def _draw_platform_section(self, subwindow, x, y, width, vals): -""" -Section providing the user's hostname, platform, and version information... - - nyx - odin (Linux 3.5.0-52-generic)Tor 0.2.5.1-alpha-dev (unrecommended) - |-- platform (40 characters) --| |--- tor version ---| -""" - -initial_x, space_left = x, min(width, 40) - -x = subwindow.addstr(x, y, vals.format('nyx - {hostname}', space_left)) -space_left -= x - initial_x - -if space_left >= 10: - subwindow.addstr(x, y, ' (%s)' % vals.format('{platform}', space_left - 3)) - -x, space_left = initial_x + 43, width - 43 - -if vals.version != 'Unknown' and space_left >= 10: - x = subwindow.addstr(x, y, vals.format('Tor {version}', space_left)) - space_left -= x - 43 - initial_x - - if space_left >= 7 + len(vals.version_status): -version_color = CONFIG['attr.version_status_colors'].get(vals.version_status, WHITE) - -x = subwindow.addstr(x, y, ' (') -x = subwindow.addstr(x, y, vals.version_status, version_color) -subwindow.addstr(x, y, ')') - def _draw_ports_section(self, subwindow, x, y, width, vals): """ Section providing our nickname, address, and port information... @@ -435,7 +406,7 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread): def _update(self): previous_height = self.get_height() -self._vals = get_sampling(self._vals) +self._vals = _get_sampling(self._vals) if self._vals.fd_used and self._vals.fd_limit != -1: fd_percent = 100 * self._vals.fd_used / self._vals.fd_limit @@ -466,7 +437,24 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread): self.redraw(True) # just need to redraw ourselves -def get_sampling(last_sampling = None): +def _sampling(**attr): + class Sampling(collections.namedtuple('Sampling', attr.keys())): +def __init__(self, **attr): + super(Sampling, self).__init__(**attr) + self._attr = attr + +def format(self, message, crop_width = None): + formatted_msg = message.format(**self._attr) + + if crop_width: +formatted_msg = str_tools.crop(formatted_msg, crop_width) + + return formatted_msg + + return Sampling(**attr) + + +def _get_sampling(last_sampling = None): controller = tor_controller() retrieved = time.time() @@ -538,17 +526,34 @@ def get_sampling(last_sampling = None): 'platform': '%s %s' % (os.uname()[0], os.uname()[2]), # [platform name] [version] } - class Sampling(collections.namedtuple('Sampling', attr.keys())): -def __init__(self, **attr): - super(Sampling, self).__init__(**attr) - self._attr = attr + return _sampling(**attr) -def format(self, message, crop_width = None): - formatted_msg = message.format(**self._attr) - if crop_width: -formatted_msg = str_tools.crop(formatted_msg, crop_width) +def _draw_platform_section(subwindow, x, y, width, vals): + """ + Section providing the user's hostname, platform, and version information... - return formatted_msg +nyx - odin (Linux 3.5.0-52-generic)Tor 0.2.5.1-alpha-dev (unrecommended) +|-- platform (40 characters) --| |--- tor version ---| + """
[tor-commits] [nyx/master] Test _draw_resource_usage()
commit 3e3443b3f995dc44a7c3886d5d5c2a8da11f5a7f Author: Damian JohnsonDate: Sat Apr 9 23:47:10 2016 -0700 Test _draw_resource_usage() --- nyx/panel/header.py | 70 +++- test/panel/header.py | 28 + 2 files changed, 64 insertions(+), 34 deletions(-) diff --git a/nyx/panel/header.py b/nyx/panel/header.py index 922b907..9e8e57d 100644 --- a/nyx/panel/header.py +++ b/nyx/panel/header.py @@ -180,6 +180,7 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread): left_width = max(subwindow.width / 2, 77) if is_wide else subwindow.width right_width = subwindow.width - left_width +pause_time = self.get_pause_time() if self.is_paused() else None _draw_platform_section(subwindow, 0, 0, left_width, vals) @@ -189,7 +190,7 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread): _draw_disconnected(subwindow, 0, 1, vals.last_heartbeat) if is_wide: - self._draw_resource_usage(subwindow, left_width, 0, right_width, vals) + _draw_resource_usage(subwindow, left_width, 0, right_width, vals, pause_time) if vals.is_relay: self._draw_fingerprint_and_fd_usage(subwindow, left_width, 1, right_width, vals) @@ -198,7 +199,7 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread): elif vals.is_connected: self._draw_newnym_option(subwindow, left_width, 1, right_width, vals) else: - self._draw_resource_usage(subwindow, 0, 2, left_width, vals) + _draw_resource_usage(subwindow, 0, 2, left_width, vals, pause_time) if vals.is_relay: self._draw_fingerprint_and_fd_usage(subwindow, 0, 3, left_width, vals) @@ -212,38 +213,6 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread): else: subwindow.addstr(0, subwindow.height - 1, 'Paused', HIGHLIGHT) - def _draw_resource_usage(self, subwindow, x, y, width, vals): -""" -System resource usage of the tor process... - - cpu: 0.0% tor, 1.0% nyxmem: 0 (0.0%) pid: 16329 uptime: 12-20:42:07 -""" - -if vals.start_time: - if not vals.is_connected: -now = vals.connection_time - elif self.is_paused(): -now = self.get_pause_time() - else: -now = time.time() - - uptime = str_tools.short_time_label(now - vals.start_time) -else: - uptime = '' - -sys_fields = ( - (0, vals.format('cpu: {tor_cpu}% tor, {nyx_cpu}% nyx')), - (27, vals.format('mem: {memory} ({memory_percent}%)')), - (47, vals.format('pid: {pid}')), - (59, 'uptime: %s' % uptime), -) - -for (start, label) in sys_fields: - if width >= start + len(label): -subwindow.addstr(x + start, y, label) - else: -break - def _draw_fingerprint_and_fd_usage(self, subwindow, x, y, width, vals): """ Presents our fingerprint, and our file descriptor usage if we're running @@ -559,3 +528,36 @@ def _draw_disconnected(subwindow, x, y, last_heartbeat): x = subwindow.addstr(x, y, 'Tor Disconnected', RED, BOLD) last_heartbeat_str = time.strftime('%H:%M %m/%d/%Y', time.localtime(last_heartbeat)) subwindow.addstr(x, y, ' (%s, press r to reconnect)' % last_heartbeat_str) + + +def _draw_resource_usage(subwindow, x, y, width, vals, pause_time): + """ + System resource usage of the tor process... + +cpu: 0.0% tor, 1.0% nyxmem: 0 (0.0%) pid: 16329 uptime: 12-20:42:07 + """ + + if vals.start_time: +if not vals.is_connected: + now = vals.connection_time +elif pause_time: + now = pause_time +else: + now = time.time() + +uptime = str_tools.short_time_label(now - vals.start_time) + else: +uptime = '' + + sys_fields = ( +(0, vals.format('cpu: {tor_cpu}% tor, {nyx_cpu}% nyx')), +(27, vals.format('mem: {memory} ({memory_percent}%)')), +(47, vals.format('pid: {pid}')), +(59, 'uptime: %s' % uptime), + ) + + for (start, label) in sys_fields: +if width >= start + len(label): + subwindow.addstr(x + start, y, label) +else: + break diff --git a/test/panel/header.py b/test/panel/header.py index 603d213..3828804 100644 --- a/test/panel/header.py +++ b/test/panel/header.py @@ -84,3 +84,31 @@ class TestHeader(unittest.TestCase): def test_draw_disconnected(self, localtime_mock): localtime_mock.return_value = time.strptime('22:43 04/09/2016', '%H:%M %m/%d/%Y') self.assertEqual('Tor Disconnected (22:43 04/09/2016, press r to reconnect)', test.render(nyx.panel.header._draw_disconnected, 0, 0, 1460267022.231895).content) + + @require_curses + def test_draw_resource_usage(self): +vals = nyx.panel.header._sampling( + start_time = 1460166022.231895, + connection_time = 1460267022.231895, + is_connected = False, + tor_cpu = '2.1', + nyx_cpu = '5.4', + memory = '118 MB', + memory_percent = '3.0', + pid = '22439', +) + +test_input = { + 80: 'cpu: 2.1%
[tor-commits] [nyx/master] Tracker could raise an unexpected CallError
commit 8bcc61c84460c31b8e56493bbf1eb306fd5839bc Author: Damian JohnsonDate: Mon Apr 11 09:07:27 2016 -0700 Tracker could raise an unexpected CallError Oops, stem's call() method raises a CallError (OSError subclass), not an IOError. Got the stacktrace while trying to get reconnection to work... File "/usr/lib/python2.7/threading.py", line 551, in __bootstrap_inner self.run() File "/home/atagar/Desktop/nyx/nyx/tracker.py", line 389, in run is_successful = self._task(self._process_pid, self._process_name) File "/home/atagar/Desktop/nyx/nyx/tracker.py", line 656, in _task total_cpu_time, uptime, memory_in_bytes, memory_in_percent = resolver(process_pid) File "/home/atagar/Desktop/nyx/nyx/tracker.py", line 213, in _resources_via_ps ps_call = system.call('ps -p {pid} -o cputime,etime,rss,%mem'.format(pid = pid)) File "/home/atagar/Desktop/nyx/stem/util/system.py", line 1080, in call raise CallError(str(exc), ' '.join(command_list), exit_status, runtime, stdout, stderr) CallError: ps -p 22439 -o cputime,etime,rss,%mem returned exit status 1 --- nyx/tracker.py | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/nyx/tracker.py b/nyx/tracker.py index 6376584..7d567a9 100644 --- a/nyx/tracker.py +++ b/nyx/tracker.py @@ -210,7 +210,10 @@ def _resources_via_ps(pid): # TIME ELAPSEDRSS %MEM # 0:04.4037:57 18772 0.9 - ps_call = system.call('ps -p {pid} -o cputime,etime,rss,%mem'.format(pid = pid)) + try: +ps_call = system.call('ps -p {pid} -o cputime,etime,rss,%mem'.format(pid = pid)) + except OSError as exc: +raise IOError(exc) if ps_call and len(ps_call) >= 2: stats = ps_call[1].strip().split() ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [nyx/master] Drop SHOW_RENDERED_CONTENT
commit e328b539f54e5864182255f6e556ae3b84e7e97e Author: Damian JohnsonDate: Mon Apr 11 09:03:05 2016 -0700 Drop SHOW_RENDERED_CONTENT Dropping a global that allowed us to pause the curses screens we render, allowing us to see what our tests generated. This was fine once upon a time but we now render too many things for it to be useful. --- test/__init__.py | 5 - 1 file changed, 5 deletions(-) diff --git a/test/__init__.py b/test/__init__.py index 23dda15..178b79d 100644 --- a/test/__init__.py +++ b/test/__init__.py @@ -20,8 +20,6 @@ __all__ = [ 'tracker', ] -SHOW_RENDERED_CONTENT = None # if set, tests render content this many seconds - OUR_SCREEN_SIZE = None TEST_SCREEN_SIZE = nyx.curses.Dimensions(80, 25) @@ -84,9 +82,6 @@ def render(func, *args, **kwargs): attr['runtime'] = time.time() - start_time attr['content'] = nyx.curses.screenshot() -if SHOW_RENDERED_CONTENT: - time.sleep(SHOW_RENDERED_CONTENT) - with patch('nyx.curses.key_input', return_value = nyx.curses.KeyInput(27)): nyx.curses.start(draw_func, transparent_background = True, cursor = False) ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [nyx/master] Test _draw_fingerprint_and_fd_usage()
commit 7b30d6fdecfe2b404188e57f81cf5fd4f8b03859 Author: Damian JohnsonDate: Sun Apr 10 11:45:30 2016 -0700 Test _draw_fingerprint_and_fd_usage() --- nyx/panel/header.py | 69 ++-- test/panel/header.py | 46 ++- 2 files changed, 80 insertions(+), 35 deletions(-) diff --git a/nyx/panel/header.py b/nyx/panel/header.py index 9e8e57d..da0ba7f 100644 --- a/nyx/panel/header.py +++ b/nyx/panel/header.py @@ -193,7 +193,7 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread): _draw_resource_usage(subwindow, left_width, 0, right_width, vals, pause_time) if vals.is_relay: -self._draw_fingerprint_and_fd_usage(subwindow, left_width, 1, right_width, vals) +_draw_fingerprint_and_fd_usage(subwindow, left_width, 1, right_width, vals) self._draw_flags(subwindow, 0, 2, left_width, vals) self._draw_exit_policy(subwindow, left_width, 2, right_width, vals) elif vals.is_connected: @@ -202,7 +202,7 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread): _draw_resource_usage(subwindow, 0, 2, left_width, vals, pause_time) if vals.is_relay: -self._draw_fingerprint_and_fd_usage(subwindow, 0, 3, left_width, vals) +_draw_fingerprint_and_fd_usage(subwindow, 0, 3, left_width, vals) self._draw_flags(subwindow, 0, 4, left_width, vals) if self._message: @@ -213,37 +213,6 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread): else: subwindow.addstr(0, subwindow.height - 1, 'Paused', HIGHLIGHT) - def _draw_fingerprint_and_fd_usage(self, subwindow, x, y, width, vals): -""" -Presents our fingerprint, and our file descriptor usage if we're running -out... - - fingerprint: 1A94D1A794FCB2F8B6CBC179EF8FDD4008A98D3B, file desc: 900 / 1000 (90%) -""" - -initial_x, space_left = x, width - -x = subwindow.addstr(x, y, vals.format('fingerprint: {fingerprint}', width)) -space_left -= x - initial_x - -if space_left >= 30 and vals.fd_used and vals.fd_limit != -1: - fd_percent = 100 * vals.fd_used / vals.fd_limit - - if fd_percent >= SHOW_FD_THRESHOLD: -if fd_percent >= 95: - percentage_format = (RED, BOLD) -elif fd_percent >= 90: - percentage_format = (RED,) -elif fd_percent >= 60: - percentage_format = (YELLOW,) -else: - percentage_format = () - -x = subwindow.addstr(x, y, ', file descriptors' if space_left >= 37 else ', file desc') -x = subwindow.addstr(x, y, vals.format(': {fd_used} / {fd_limit} (')) -x = subwindow.addstr(x, y, '%i%%' % fd_percent, *percentage_format) -subwindow.addstr(x, y, ')') - def _draw_flags(self, subwindow, x, y, width, vals): """ Presents flags held by our relay... @@ -377,7 +346,7 @@ def _sampling(**attr): def format(self, message, crop_width = None): formatted_msg = message.format(**self._attr) - if crop_width: + if crop_width is not None: formatted_msg = str_tools.crop(formatted_msg, crop_width) return formatted_msg @@ -561,3 +530,35 @@ def _draw_resource_usage(subwindow, x, y, width, vals, pause_time): subwindow.addstr(x + start, y, label) else: break + + +def _draw_fingerprint_and_fd_usage(subwindow, x, y, width, vals): + """ + Presents our fingerprint, and our file descriptor usage if we're running + out... + +fingerprint: 1A94D1A794FCB2F8B6CBC179EF8FDD4008A98D3B, file desc: 900 / 1000 (90%) + """ + + initial_x, space_left = x, width + + x = subwindow.addstr(x, y, vals.format('fingerprint: {fingerprint}', width)) + space_left -= x - initial_x + + if space_left >= 30 and vals.fd_used and vals.fd_limit != -1: +fd_percent = 100 * vals.fd_used / vals.fd_limit + +if fd_percent >= SHOW_FD_THRESHOLD: + if fd_percent >= 95: +percentage_format = (RED, BOLD) + elif fd_percent >= 90: +percentage_format = (RED,) + elif fd_percent >= 60: +percentage_format = (YELLOW,) + else: +percentage_format = () + + x = subwindow.addstr(x, y, ', file descriptors' if space_left >= 37 else ', file desc') + x = subwindow.addstr(x, y, vals.format(': {fd_used} / {fd_limit} (')) + x = subwindow.addstr(x, y, '%i%%' % fd_percent, *percentage_format) + subwindow.addstr(x, y, ')') diff --git a/test/panel/header.py b/test/panel/header.py index 3828804..0d80f0f 100644 --- a/test/panel/header.py +++ b/test/panel/header.py @@ -31,7 +31,7 @@ class TestHeader(unittest.TestCase): 30: 'nyx - odin (Linux 3.5.0-54...)', 20: 'nyx - odin (Linu...)', 10: 'nyx - odin', - 0: 'nyx - odin', + 0: '', } for width, expected in test_input.items(): @@ -112,3 +112,47 @@ class TestHeader(unittest.TestCase): for width, expected in test_input.items(): self.assertEqual(expected,
[tor-commits] [nyx/master] Move SYSTEM_CALL_TIME to Stem
commit 1c3fc574c3a2303189306bdc74c32add20423a03 Author: Damian JohnsonDate: Sat Apr 16 12:09:25 2016 -0700 Move SYSTEM_CALL_TIME to Stem On reflection SYSTEM_CALL_TIME better belongs in Stem itself. No need any longer for this wrapper. --- nyx/panel/header.py | 24 +--- test/panel/header.py | 5 - 2 files changed, 1 insertion(+), 28 deletions(-) diff --git a/nyx/panel/header.py b/nyx/panel/header.py index f29d232..4e4f922 100644 --- a/nyx/panel/header.py +++ b/nyx/panel/header.py @@ -31,13 +31,6 @@ MIN_DUAL_COL_WIDTH = 141 # minimum width where we'll show two columns SHOW_FD_THRESHOLD = 60 # show file descriptor usage if usage is over this percentage UPDATE_RATE = 5 # rate in seconds at which we refresh -# Tracks total time spent shelling out to other commands like 'ps' and -# 'netstat', so we can account for it as part of our cpu time. - -SYSTEM_CALL_TIME = 0.0 -SYSTEM_CALL_TIME_LOCK = threading.RLock() -SYSTEM_CALL_ORIG = stem.util.system.call - CONFIG = conf.config_dict('nyx', { 'attr.flag_colors': {}, 'attr.version_status_colors': {}, @@ -45,21 +38,6 @@ CONFIG = conf.config_dict('nyx', { }) -def call_wrapper(*args, **kwargs): - global SYSTEM_CALL_TIME - - start_time = time.time() - - try: -return SYSTEM_CALL_ORIG(*args, **kwargs) - finally: -with SYSTEM_CALL_TIME_LOCK: - SYSTEM_CALL_TIME += time.time() - start_time - - -stem.util.system.call = call_wrapper - - class HeaderPanel(nyx.panel.Panel, threading.Thread): """ Top area containing tor settings and system information. @@ -307,7 +285,7 @@ class Sampling(object): pid = controller.get_pid('') tor_resources = nyx.tracker.get_resource_tracker().get_value() -nyx_total_cpu_time = sum(os.times()[:3], SYSTEM_CALL_TIME) +nyx_total_cpu_time = sum(os.times()[:3], stem.util.system.SYSTEM_CALL_TIME) or_listeners = controller.get_listeners(stem.control.Listener.OR, []) control_listeners = controller.get_listeners(stem.control.Listener.CONTROL, []) diff --git a/test/panel/header.py b/test/panel/header.py index 6e0f275..e601f00 100644 --- a/test/panel/header.py +++ b/test/panel/header.py @@ -18,11 +18,6 @@ from mock import patch, Mock class TestHeader(unittest.TestCase): - def test_system_call_time_tracked(self): -initial = nyx.panel.header.SYSTEM_CALL_TIME -stem.util.system.call('sleep 0.5') -self.assertTrue(nyx.panel.header.SYSTEM_CALL_TIME - initial > 0.4) - @patch('nyx.panel.header.tor_controller') @patch('nyx.tracker.get_resource_tracker') @patch('time.time', Mock(return_value = 1234.5)) ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [nyx/master] Change keybinding for resizing graph to 'g'
commit 03e02165fa723a1a619ac46788c4ef2f17967682 Author: Damian JohnsonDate: Mon Apr 11 09:15:26 2016 -0700 Change keybinding for resizing graph to 'g' The 'r' keybinding conflicted with reconnecting to tor. --- nyx/panel/graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nyx/panel/graph.py b/nyx/panel/graph.py index 401c079..48cf3b9 100644 --- a/nyx/panel/graph.py +++ b/nyx/panel/graph.py @@ -522,7 +522,7 @@ class GraphPanel(nyx.panel.Panel): self.redraw(True) return ( - nyx.panel.KeyHandler('r', 'resize graph', self.resize_graph), + nyx.panel.KeyHandler('g', 'resize graph', self.resize_graph), nyx.panel.KeyHandler('s', 'graphed stats', _pick_stats, self.displayed_stat if self.displayed_stat else 'none'), nyx.panel.KeyHandler('b', 'graph bounds', _next_bounds, self.bounds_type.replace('_', ' ')), nyx.panel.KeyHandler('i', 'graph update interval', _pick_interval, self.update_interval), ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [nyx/master] Test Sampling
commit c4b69ad5051d51b11ba5b6f2c931e1d604afd903 Author: Damian JohnsonDate: Sun Apr 10 16:44:03 2016 -0700 Test Sampling --- test/panel/header.py | 101 ++- 1 file changed, 100 insertions(+), 1 deletion(-) diff --git a/test/panel/header.py b/test/panel/header.py index 57222b0..7ea2510 100644 --- a/test/panel/header.py +++ b/test/panel/header.py @@ -6,14 +6,112 @@ import time import unittest import nyx.panel.header +import stem.control import stem.exit_policy +import stem.version import test from test import require_curses -from mock import patch +from mock import patch, Mock class TestHeader(unittest.TestCase): + @patch('nyx.panel.header.tor_controller') + @patch('nyx.tracker.get_resource_tracker') + @patch('time.time', Mock(return_value = 1234.5)) + @patch('os.times', Mock(return_value = (0.08, 0.03, 0.0, 0.0, 18759021.31))) + @patch('os.uname', Mock(return_value = ('Linux', 'odin', '3.5.0-54-generic', '#81~precise1-Ubuntu SMP Tue Jul 15 04:05:58 UTC 2014', 'i686'))) + @patch('nyx.panel.header.system.start_time', Mock(return_value = 5678)) + @patch('nyx.panel.header.proc.file_descriptors_used', Mock(return_value = 89)) + def test_sample(self, resource_tracker_mock, tor_controller_mock): +tor_controller_mock().is_alive.return_value = True +tor_controller_mock().connection_time.return_value = 567.8 +tor_controller_mock().get_latest_heartbeat.return_value = 89.0 +tor_controller_mock().get_newnym_wait.return_value = 0 +tor_controller_mock().get_exit_policy.return_value = stem.exit_policy.ExitPolicy('reject *:*') +tor_controller_mock().get_network_status.return_value = None +tor_controller_mock().get_version.return_value = stem.version.Version('0.1.2.3-tag') +tor_controller_mock().get_pid.return_value = '123' + +tor_controller_mock().get_info.side_effect = lambda param, default = None: { + 'fingerprint': '1A94D1A794FCB2F8B6CBC179EF8FDD4008A98D3B', + 'status/version/current': 'recommended', + 'address': '174.21.17.28', + 'process/descriptor-limit': 678, +}[param] + +tor_controller_mock().get_conf.side_effect = lambda param, default = None: { + 'Nickname': 'Unnamed', + 'HashedControlPassword': None, + 'CookieAuthentication': '1', + 'DirPort': '7001', + 'ControlSocket': None, +}[param] + +tor_controller_mock().get_listeners.side_effect = lambda param, default = None: { + stem.control.Listener.OR: [('0.0.0.0', 7000)], + stem.control.Listener.CONTROL: [('0.0.0.0', 9051)], +}[param] + +resources = Mock() +resources.cpu_sample = 6.7 +resources.memory_bytes = 62464 +resources.memory_percent = .125 + +resource_tracker_mock().get_value.return_value = resources + +vals = nyx.panel.header.Sampling.create() + +self.assertEqual(1234.5, vals.retrieved) +self.assertEqual(True, vals.is_connected) +self.assertEqual(567.8, vals.connection_time) +self.assertEqual(89.0, vals.last_heartbeat) +self.assertEqual('1A94D1A794FCB2F8B6CBC179EF8FDD4008A98D3B', vals.fingerprint) +self.assertEqual('Unnamed', vals.nickname) +self.assertEqual(0, vals.newnym_wait) +self.assertEqual(stem.exit_policy.ExitPolicy('reject *:*'), vals.exit_policy) +self.assertEqual([], vals.flags) +self.assertEqual('0.1.2.3-tag', vals.version) +self.assertEqual('recommended', vals.version_status) +self.assertEqual('174.21.17.28', vals.address) +self.assertEqual(7000, vals.or_port) +self.assertEqual('7001', vals.dir_port) +self.assertEqual('9051', vals.control_port) +self.assertEqual(None, vals.socket_path) +self.assertEqual(True, vals.is_relay) +self.assertEqual('cookie', vals.auth_type) +self.assertEqual('123', vals.pid) +self.assertEqual(5678, vals.start_time) +self.assertEqual(678, vals.fd_limit) +self.assertEqual(89, vals.fd_used) +self.assertEqual(0.11, vals.nyx_total_cpu_time) +self.assertEqual('670.0', vals.tor_cpu) +self.assertEqual('0.0', vals.nyx_cpu) +self.assertEqual('61 KB', vals.memory) +self.assertEqual('12.5', vals.memory_percent) +self.assertEqual('odin', vals.hostname) +self.assertEqual('Linux 3.5.0-54-generic', vals.platform) + + def test_sample_format(self): +vals = nyx.panel.header.Sampling( + version = '0.2.8.1', + version_status = 'unrecommended', +) + +self.assertEqual('0.2.8.1 is unrecommended', vals.format('{version} is {version_status}')) + +test_input = { + 25: '0.2.8.1 is unrecommended', + 20: '0.2.8.1 is unreco...', + 15: '0.2.8.1 is...', + 10: '0.2.8.1...', + 5: '', + 0: '', +} + +for width, expected in test_input.items(): + self.assertEqual(expected, vals.format('{version} is {version_status}', width)) + @require_curses def test_draw_platform_section(self): vals = nyx.panel.header.Sampling( @@
[tor-commits] [nyx/master] Class for Sampling rather than namedtuple
commit da39c3fedd7e7345d4e587ba2fe571369c6d9add Author: Damian JohnsonDate: Sun Apr 10 13:12:16 2016 -0700 Class for Sampling rather than namedtuple As mentioned earlier I didn't like the sampling() and get_sampling() split we needed for our tests. On reflection this is actually nicer if we simply don't strive to make this a namedtuple. --- nyx/panel/header.py | 166 +-- test/panel/header.py | 14 ++--- 2 files changed, 89 insertions(+), 91 deletions(-) diff --git a/nyx/panel/header.py b/nyx/panel/header.py index 9288db9..01922ec 100644 --- a/nyx/panel/header.py +++ b/nyx/panel/header.py @@ -7,7 +7,6 @@ This expands the information it presents to two columns if there's room available. """ -import collections import os import time import threading @@ -45,7 +44,7 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread): threading.Thread.__init__(self) self.setDaemon(True) -self._vals = _get_sampling() +self._vals = Sampling.create() self._last_width = 100 self._pause_condition = threading.Condition() @@ -248,7 +247,7 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread): def _update(self): previous_height = self.get_height() -self._vals = _get_sampling(self._vals) +self._vals = Sampling.create(self._vals) if self._vals.fd_used and self._vals.fd_limit != -1: fd_percent = 100 * self._vals.fd_used / self._vals.fd_limit @@ -279,96 +278,95 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread): self.redraw(True) # just need to redraw ourselves -def _sampling(**attr): - class Sampling(collections.namedtuple('Sampling', attr.keys())): -def __init__(self, **attr): - super(Sampling, self).__init__(**attr) - self._attr = attr +class Sampling(object): + def __init__(self, **attr): +self._attr = attr -def format(self, message, crop_width = None): - formatted_msg = message.format(**self._attr) +for key, value in attr.items(): + setattr(self, key, value) - if crop_width is not None: -formatted_msg = str_tools.crop(formatted_msg, crop_width) - - return formatted_msg - - return Sampling(**attr) - - -def _get_sampling(last_sampling = None): - controller = tor_controller() - retrieved = time.time() + @staticmethod + def create(last_sampling = None): +controller = tor_controller() +retrieved = time.time() - pid = controller.get_pid('') - tor_resources = nyx.tracker.get_resource_tracker().get_value() - nyx_total_cpu_time = sum(os.times()[:3]) +pid = controller.get_pid('') +tor_resources = nyx.tracker.get_resource_tracker().get_value() +nyx_total_cpu_time = sum(os.times()[:3]) - or_listeners = controller.get_listeners(Listener.OR, []) - control_listeners = controller.get_listeners(Listener.CONTROL, []) +or_listeners = controller.get_listeners(Listener.OR, []) +control_listeners = controller.get_listeners(Listener.CONTROL, []) - if controller.get_conf('HashedControlPassword', None): -auth_type = 'password' - elif controller.get_conf('CookieAuthentication', None) == '1': -auth_type = 'cookie' - else: -auth_type = 'open' +if controller.get_conf('HashedControlPassword', None): + auth_type = 'password' +elif controller.get_conf('CookieAuthentication', None) == '1': + auth_type = 'cookie' +else: + auth_type = 'open' - try: -fd_used = proc.file_descriptors_used(pid) - except IOError: -fd_used = None +try: + fd_used = proc.file_descriptors_used(pid) +except IOError: + fd_used = None - if last_sampling: -nyx_cpu_delta = nyx_total_cpu_time - last_sampling.nyx_total_cpu_time -nyx_time_delta = retrieved - last_sampling.retrieved +if last_sampling: + nyx_cpu_delta = nyx_total_cpu_time - last_sampling.nyx_total_cpu_time + nyx_time_delta = retrieved - last_sampling.retrieved -python_cpu_time = nyx_cpu_delta / nyx_time_delta -sys_call_cpu_time = 0.0 # TODO: add a wrapper around call() to get this + python_cpu_time = nyx_cpu_delta / nyx_time_delta + sys_call_cpu_time = 0.0 # TODO: add a wrapper around call() to get this -nyx_cpu = python_cpu_time + sys_call_cpu_time - else: -nyx_cpu = 0.0 - - attr = { -'retrieved': retrieved, -'is_connected': controller.is_alive(), -'connection_time': controller.connection_time(), -'last_heartbeat': controller.get_latest_heartbeat(), - -'fingerprint': controller.get_info('fingerprint', 'Unknown'), -'nickname': controller.get_conf('Nickname', ''), -'newnym_wait': controller.get_newnym_wait(), -'exit_policy': controller.get_exit_policy(None), -'flags': getattr(controller.get_network_status(default = None), 'flags', []), - -'version': str(controller.get_version('Unknown')).split()[0], -'version_status': controller.get_info('status/version/current',
[tor-commits] [nyx/master] Account for subcommands in nyx cpu usage
commit 3148caa37ba406610ddb0187468107205581c105 Author: Damian JohnsonDate: Wed Apr 13 10:10:04 2016 -0700 Account for subcommands in nyx cpu usage Shelling out to other commands isn't accounted for in os.times(). As such wrapping stem's call() function so shelling out is accounted for in the nyx cpu usage we show. --- nyx/panel/header.py | 53 test/panel/header.py | 13 ++--- 2 files changed, 47 insertions(+), 19 deletions(-) diff --git a/nyx/panel/header.py b/nyx/panel/header.py index 998a20d..f29d232 100644 --- a/nyx/panel/header.py +++ b/nyx/panel/header.py @@ -12,14 +12,17 @@ import time import threading import stem +import stem.control +import stem.util.proc +import stem.util.str_tools +import stem.util.system import nyx.controller import nyx.panel import nyx.popups import nyx.tracker -from stem.control import Listener, State -from stem.util import conf, log, proc, str_tools, system +from stem.util import conf, log from nyx import msg, tor_controller from nyx.curses import RED, GREEN, YELLOW, CYAN, WHITE, BOLD, HIGHLIGHT @@ -28,6 +31,13 @@ MIN_DUAL_COL_WIDTH = 141 # minimum width where we'll show two columns SHOW_FD_THRESHOLD = 60 # show file descriptor usage if usage is over this percentage UPDATE_RATE = 5 # rate in seconds at which we refresh +# Tracks total time spent shelling out to other commands like 'ps' and +# 'netstat', so we can account for it as part of our cpu time. + +SYSTEM_CALL_TIME = 0.0 +SYSTEM_CALL_TIME_LOCK = threading.RLock() +SYSTEM_CALL_ORIG = stem.util.system.call + CONFIG = conf.config_dict('nyx', { 'attr.flag_colors': {}, 'attr.version_status_colors': {}, @@ -35,6 +45,21 @@ CONFIG = conf.config_dict('nyx', { }) +def call_wrapper(*args, **kwargs): + global SYSTEM_CALL_TIME + + start_time = time.time() + + try: +return SYSTEM_CALL_ORIG(*args, **kwargs) + finally: +with SYSTEM_CALL_TIME_LOCK: + SYSTEM_CALL_TIME += time.time() - start_time + + +stem.util.system.call = call_wrapper + + class HeaderPanel(nyx.panel.Panel, threading.Thread): """ Top area containing tor settings and system information. @@ -232,7 +257,7 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread): def reset_listener(self, controller, event_type, _): self._update() -if event_type == State.CLOSED: +if event_type == stem.control.State.CLOSED: log.notice('Tor control port closed') def _update(self): @@ -282,10 +307,10 @@ class Sampling(object): pid = controller.get_pid('') tor_resources = nyx.tracker.get_resource_tracker().get_value() -nyx_total_cpu_time = sum(os.times()[:3]) +nyx_total_cpu_time = sum(os.times()[:3], SYSTEM_CALL_TIME) -or_listeners = controller.get_listeners(Listener.OR, []) -control_listeners = controller.get_listeners(Listener.CONTROL, []) +or_listeners = controller.get_listeners(stem.control.Listener.OR, []) +control_listeners = controller.get_listeners(stem.control.Listener.CONTROL, []) if controller.get_conf('HashedControlPassword', None): auth_type = 'password' @@ -295,18 +320,14 @@ class Sampling(object): auth_type = 'open' try: - fd_used = proc.file_descriptors_used(pid) + fd_used = stem.util.proc.file_descriptors_used(pid) except IOError: fd_used = None if last_sampling: nyx_cpu_delta = nyx_total_cpu_time - last_sampling.nyx_total_cpu_time nyx_time_delta = retrieved - last_sampling.retrieved - - python_cpu_time = nyx_cpu_delta / nyx_time_delta - sys_call_cpu_time = 0.0 # TODO: add a wrapper around call() to get this - - nyx_cpu = python_cpu_time + sys_call_cpu_time + nyx_cpu = nyx_cpu_delta / nyx_time_delta else: nyx_cpu = 0.0 @@ -334,14 +355,14 @@ class Sampling(object): 'auth_type': auth_type, 'pid': pid, - 'start_time': system.start_time(pid), + 'start_time': stem.util.system.start_time(pid), 'fd_limit': int(controller.get_info('process/descriptor-limit', '-1')), 'fd_used': fd_used, 'nyx_total_cpu_time': nyx_total_cpu_time, 'tor_cpu': '%0.1f' % (100 * tor_resources.cpu_sample), 'nyx_cpu': '%0.1f' % (nyx_cpu), - 'memory': str_tools.size_label(tor_resources.memory_bytes) if tor_resources.memory_bytes > 0 else 0, + 'memory': stem.util.str_tools.size_label(tor_resources.memory_bytes) if tor_resources.memory_bytes > 0 else 0, 'memory_percent': '%0.1f' % (100 * tor_resources.memory_percent), 'hostname': os.uname()[1], @@ -354,7 +375,7 @@ class Sampling(object): formatted_msg = message.format(**self._attr) if crop_width is not None: - formatted_msg = str_tools.crop(formatted_msg, crop_width) + formatted_msg = stem.util.str_tools.crop(formatted_msg, crop_width) return formatted_msg @@ -444,7 +465,7 @@ def
[tor-commits] [nyx/master] Test _draw_ports_section()
commit 6159e01fdc1473fd25f3633b154a74cdac20ef8d Author: Damian JohnsonDate: Sat Apr 9 22:32:39 2016 -0700 Test _draw_ports_section() --- nyx/panel/header.py | 56 ++-- test/panel/header.py | 31 + 2 files changed, 59 insertions(+), 28 deletions(-) diff --git a/nyx/panel/header.py b/nyx/panel/header.py index f49efe1..54046b2 100644 --- a/nyx/panel/header.py +++ b/nyx/panel/header.py @@ -184,7 +184,7 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread): _draw_platform_section(subwindow, 0, 0, left_width, vals) if vals.is_connected: - self._draw_ports_section(subwindow, 0, 1, left_width, vals) + _draw_ports_section(subwindow, 0, 1, left_width, vals) else: self._draw_disconnected(subwindow, 0, 1, left_width, vals) @@ -212,33 +212,6 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread): else: subwindow.addstr(0, subwindow.height - 1, 'Paused', HIGHLIGHT) - def _draw_ports_section(self, subwindow, x, y, width, vals): -""" -Section providing our nickname, address, and port information... - - Unnamed - 0.0.0.0:7000, Control Port (cookie): 9051 -""" - -if not vals.is_relay: - x = subwindow.addstr(x, y, 'Relaying Disabled', CYAN) -else: - x = subwindow.addstr(x, y, vals.format('{nickname} - {address}:{or_port}')) - - if vals.dir_port != '0': -x = subwindow.addstr(x, y, vals.format(', Dir Port: {dir_port}')) - -if vals.control_port: - if width >= x + 19 + len(vals.control_port) + len(vals.auth_type): -auth_color = RED if vals.auth_type == 'open' else GREEN - -x = subwindow.addstr(x, y, ', Control Port (') -x = subwindow.addstr(x, y, vals.auth_type, auth_color) -subwindow.addstr(x, y, vals.format('): {control_port}')) - else: -subwindow.addstr(x, y, vals.format(', Control Port: {control_port}')) -elif vals.socket_path: - subwindow.addstr(x, y, vals.format(', Control Socket: {socket_path}')) - def _draw_disconnected(self, subwindow, x, y, width, vals): """ Message indicating that tor is disconnected... @@ -557,3 +530,30 @@ def _draw_platform_section(subwindow, x, y, width, vals): x = subwindow.addstr(x, y, ' (') x = subwindow.addstr(x, y, vals.version_status, version_color) subwindow.addstr(x, y, ')') + +def _draw_ports_section(subwindow, x, y, width, vals): + """ + Section providing our nickname, address, and port information... + +Unnamed - 0.0.0.0:7000, Control Port (cookie): 9051 + """ + + if not vals.is_relay: +x = subwindow.addstr(x, y, 'Relaying Disabled', CYAN) + else: +x = subwindow.addstr(x, y, vals.format('{nickname} - {address}:{or_port}')) + +if vals.dir_port != '0': + x = subwindow.addstr(x, y, vals.format(', Dir Port: {dir_port}')) + + if vals.control_port: +if width >= x + 19 + len(vals.control_port) + len(vals.auth_type): + auth_color = RED if vals.auth_type == 'open' else GREEN + + x = subwindow.addstr(x, y, ', Control Port (') + x = subwindow.addstr(x, y, vals.auth_type, auth_color) + subwindow.addstr(x, y, vals.format('): {control_port}')) +else: + subwindow.addstr(x, y, vals.format(', Control Port: {control_port}')) + elif vals.socket_path: +subwindow.addstr(x, y, vals.format(', Control Socket: {socket_path}')) diff --git a/test/panel/header.py b/test/panel/header.py index ee18eb6..c06fd39 100644 --- a/test/panel/header.py +++ b/test/panel/header.py @@ -45,3 +45,34 @@ class TestHeader(unittest.TestCase): rendered = test.render(nyx.panel.header._draw_platform_section, 0, 0, 80, vals) self.assertEqual('nyx - odin (Linux 3.5.0-54-generic)', rendered.content) + + @require_curses + def test_draw_ports_section(self): +vals = nyx.panel.header._sampling( + nickname = 'Unnamed', + address = '174.21.17.28', + or_port = '7000', + dir_port = '7001', + control_port = '9051', + auth_type = 'cookie', + is_relay = True, +) + +test_input = { + 80: 'Unnamed - 174.21.17.28:7000, Dir Port: 7001, Control Port (cookie): 9051', + 50: 'Unnamed - 174.21.17.28:7000, Dir Port: 7001, Control Port: 9051', + 0: 'Unnamed - 174.21.17.28:7000, Dir Port: 7001, Control Port: 9051', +} + +for width, expected in test_input.items(): + self.assertEqual(expected, test.render(nyx.panel.header._draw_ports_section, 0, 0, width, vals).content) + + @require_curses + def test_draw_ports_section_with_relaying(self): +vals = nyx.panel.header._sampling( + control_port = None, + socket_path = '/path/to/control/socket', + is_relay = False, +) + +self.assertEqual('Relaying Disabled, Control Socket: /path/to/control/socket', test.render(nyx.panel.header._draw_ports_section, 0, 0, 80, vals).content) ___
[tor-commits] [nyx/master] Test _draw_exit_policy()
commit 09c23a7433d4710c8c88962c7b4acc3f21dcc5d0 Author: Damian JohnsonDate: Sun Apr 10 13:00:53 2016 -0700 Test _draw_exit_policy() --- nyx/panel/header.py | 57 ++-- test/panel/header.py | 6 ++ 2 files changed, 35 insertions(+), 28 deletions(-) diff --git a/nyx/panel/header.py b/nyx/panel/header.py index 00d4794..96b8383 100644 --- a/nyx/panel/header.py +++ b/nyx/panel/header.py @@ -195,7 +195,7 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread): if vals.is_relay: _draw_fingerprint_and_fd_usage(subwindow, left_width, 1, right_width, vals) _draw_flags(subwindow, 0, 2, vals.flags) -self._draw_exit_policy(subwindow, left_width, 2, right_width, vals) +_draw_exit_policy(subwindow, left_width, 2, vals.exit_policy) elif vals.is_connected: self._draw_newnym_option(subwindow, left_width, 1, right_width, vals) else: @@ -213,33 +213,6 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread): else: subwindow.addstr(0, subwindow.height - 1, 'Paused', HIGHLIGHT) - def _draw_exit_policy(self, subwindow, x, y, width, vals): -""" -Presents our exit policy... - - exit policy: reject *:* -""" - -x = subwindow.addstr(x, y, 'exit policy: ') - -if not vals.exit_policy: - return - -rules = list(vals.exit_policy.strip_private().strip_default()) - -for i, rule in enumerate(rules): - policy_color = GREEN if rule.is_accept else RED - x = subwindow.addstr(x, y, str(rule), policy_color, BOLD) - - if i < len(rules) - 1: -x = subwindow.addstr(x, y, ', ') - -if vals.exit_policy.has_default(): - if rules: -x = subwindow.addstr(x, y, ', ') - - subwindow.addstr(x, y, '', CYAN, BOLD) - def _draw_newnym_option(self, subwindow, x, y, width, vals): """ Provide a notice for requiesting a new identity, and time until it's next @@ -563,3 +536,31 @@ def _draw_flags(subwindow, x, y, flags): x = subwindow.addstr(x, y, ', ') else: subwindow.addstr(x, y, 'none', CYAN, BOLD) + + +def _draw_exit_policy(subwindow, x, y, exit_policy): + """ + Presents our exit policy... + +exit policy: reject *:* + """ + + x = subwindow.addstr(x, y, 'exit policy: ') + + if not exit_policy: +return + + rules = list(exit_policy.strip_private().strip_default()) + + for i, rule in enumerate(rules): +policy_color = GREEN if rule.is_accept else RED +x = subwindow.addstr(x, y, str(rule), policy_color, BOLD) + +if i < len(rules) - 1: + x = subwindow.addstr(x, y, ', ') + + if exit_policy.has_default(): +if rules: + x = subwindow.addstr(x, y, ', ') + +subwindow.addstr(x, y, '', CYAN, BOLD) diff --git a/test/panel/header.py b/test/panel/header.py index 39982e0..9794644 100644 --- a/test/panel/header.py +++ b/test/panel/header.py @@ -6,6 +6,7 @@ import time import unittest import nyx.panel.header +import stem.exit_policy import test from test import require_curses @@ -162,3 +163,8 @@ class TestHeader(unittest.TestCase): self.assertEqual('flags: none', test.render(nyx.panel.header._draw_flags, 0, 0, []).content) self.assertEqual('flags: Guard', test.render(nyx.panel.header._draw_flags, 0, 0, ['Guard']).content) self.assertEqual('flags: Running, Exit', test.render(nyx.panel.header._draw_flags, 0, 0, ['Running', 'Exit']).content) + + @require_curses + def test_draw_exit_policy(self): +self.assertEqual('exit policy: reject *:*', test.render(nyx.panel.header._draw_exit_policy, 0, 0, stem.exit_policy.ExitPolicy('reject *:*')).content) +self.assertEqual('exit policy: accept *:80, accept *:443, reject *:*', test.render(nyx.panel.header._draw_exit_policy, 0, 0, stem.exit_policy.ExitPolicy('accept *:80', 'accept *:443', 'reject *:*')).content) ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [nyx/master] Test _draw_disconnected()
commit 6cc017c0a67a6a8fe7038f229b3111743ec5b6ef Author: Damian JohnsonDate: Sat Apr 9 23:06:23 2016 -0700 Test _draw_disconnected() --- nyx/panel/header.py | 26 ++ test/panel/header.py | 8 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/nyx/panel/header.py b/nyx/panel/header.py index 54046b2..922b907 100644 --- a/nyx/panel/header.py +++ b/nyx/panel/header.py @@ -186,7 +186,7 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread): if vals.is_connected: _draw_ports_section(subwindow, 0, 1, left_width, vals) else: - self._draw_disconnected(subwindow, 0, 1, left_width, vals) + _draw_disconnected(subwindow, 0, 1, vals.last_heartbeat) if is_wide: self._draw_resource_usage(subwindow, left_width, 0, right_width, vals) @@ -212,17 +212,6 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread): else: subwindow.addstr(0, subwindow.height - 1, 'Paused', HIGHLIGHT) - def _draw_disconnected(self, subwindow, x, y, width, vals): -""" -Message indicating that tor is disconnected... - - Tor Disconnected (15:21 07/13/2014, press r to reconnect) -""" - -x = subwindow.addstr(x, y, 'Tor Disconnected', RED, BOLD) -last_heartbeat = time.strftime('%H:%M %m/%d/%Y', time.localtime(vals.last_heartbeat)) -subwindow.addstr(x, y, ' (%s, press r to reconnect)' % last_heartbeat) - def _draw_resource_usage(self, subwindow, x, y, width, vals): """ System resource usage of the tor process... @@ -531,6 +520,7 @@ def _draw_platform_section(subwindow, x, y, width, vals): x = subwindow.addstr(x, y, vals.version_status, version_color) subwindow.addstr(x, y, ')') + def _draw_ports_section(subwindow, x, y, width, vals): """ Section providing our nickname, address, and port information... @@ -557,3 +547,15 @@ def _draw_ports_section(subwindow, x, y, width, vals): subwindow.addstr(x, y, vals.format(', Control Port: {control_port}')) elif vals.socket_path: subwindow.addstr(x, y, vals.format(', Control Socket: {socket_path}')) + + +def _draw_disconnected(subwindow, x, y, last_heartbeat): + """ + Message indicating that tor is disconnected... + +Tor Disconnected (15:21 07/13/2014, press r to reconnect) + """ + + x = subwindow.addstr(x, y, 'Tor Disconnected', RED, BOLD) + last_heartbeat_str = time.strftime('%H:%M %m/%d/%Y', time.localtime(last_heartbeat)) + subwindow.addstr(x, y, ' (%s, press r to reconnect)' % last_heartbeat_str) diff --git a/test/panel/header.py b/test/panel/header.py index c06fd39..603d213 100644 --- a/test/panel/header.py +++ b/test/panel/header.py @@ -2,12 +2,14 @@ Unit tests for nyx.panel.header. """ +import time import unittest import nyx.panel.header import test from test import require_curses +from mock import patch class TestHeader(unittest.TestCase): @@ -76,3 +78,9 @@ class TestHeader(unittest.TestCase): ) self.assertEqual('Relaying Disabled, Control Socket: /path/to/control/socket', test.render(nyx.panel.header._draw_ports_section, 0, 0, 80, vals).content) + + @require_curses + @patch('time.localtime') + def test_draw_disconnected(self, localtime_mock): +localtime_mock.return_value = time.strptime('22:43 04/09/2016', '%H:%M %m/%d/%Y') +self.assertEqual('Tor Disconnected (22:43 04/09/2016, press r to reconnect)', test.render(nyx.panel.header._draw_disconnected, 0, 0, 1460267022.231895).content) ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [nyx/master] Use draw() for header panel
commit 1154e051ac7bb4f30631a52797b647516471cd35 Author: Damian JohnsonDate: Sat Apr 9 14:45:54 2016 -0700 Use draw() for header panel First step in migrating the panels to the new Subwindow pattern. Not quite happy with this yet but it's a good start and works. --- nyx/panel/__init__.py | 7 +++ nyx/panel/header.py | 118 +- 2 files changed, 66 insertions(+), 59 deletions(-) diff --git a/nyx/panel/__init__.py b/nyx/panel/__init__.py index 9b616e5..028ba73 100644 --- a/nyx/panel/__init__.py +++ b/nyx/panel/__init__.py @@ -339,6 +339,13 @@ class Panel(object): if not self.visible or HALT_ACTIVITY: return +if self.panel_name in ('header'): + height = self.get_height() if self.get_height() != -1 else None + width = self.get_width() if self.get_width() != -1 else None + + nyx.curses.draw(self.draw, top = self.top, width = width, height = height) + return + # if the panel's completely outside its parent then this is a no-op new_height, new_width = self.get_preferred_size() diff --git a/nyx/panel/header.py b/nyx/panel/header.py index c6627c2..8efbf8e 100644 --- a/nyx/panel/header.py +++ b/nyx/panel/header.py @@ -171,48 +171,48 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread): nyx.panel.KeyHandler('r', action = _reconnect), ) - def draw(self, width, height): + def draw(self, subwindow): vals = self._vals # local reference to avoid concurrency concerns -self._last_width = width +self._last_width = subwindow.width is_wide = self.is_wide() # space available for content -left_width = max(width / 2, 77) if is_wide else width -right_width = width - left_width +left_width = max(subwindow.width / 2, 77) if is_wide else subwindow.width +right_width = subwindow.width - left_width -self._draw_platform_section(0, 0, left_width, vals) +self._draw_platform_section(subwindow, 0, 0, left_width, vals) if vals.is_connected: - self._draw_ports_section(0, 1, left_width, vals) + self._draw_ports_section(subwindow, 0, 1, left_width, vals) else: - self._draw_disconnected(0, 1, left_width, vals) + self._draw_disconnected(subwindow, 0, 1, left_width, vals) if is_wide: - self._draw_resource_usage(left_width, 0, right_width, vals) + self._draw_resource_usage(subwindow, left_width, 0, right_width, vals) if vals.is_relay: -self._draw_fingerprint_and_fd_usage(left_width, 1, right_width, vals) -self._draw_flags(0, 2, left_width, vals) -self._draw_exit_policy(left_width, 2, right_width, vals) +self._draw_fingerprint_and_fd_usage(subwindow, left_width, 1, right_width, vals) +self._draw_flags(subwindow, 0, 2, left_width, vals) +self._draw_exit_policy(subwindow, left_width, 2, right_width, vals) elif vals.is_connected: -self._draw_newnym_option(left_width, 1, right_width, vals) +self._draw_newnym_option(subwindow, left_width, 1, right_width, vals) else: - self._draw_resource_usage(0, 2, left_width, vals) + self._draw_resource_usage(subwindow, 0, 2, left_width, vals) if vals.is_relay: -self._draw_fingerprint_and_fd_usage(0, 3, left_width, vals) -self._draw_flags(0, 4, left_width, vals) +self._draw_fingerprint_and_fd_usage(subwindow, 0, 3, left_width, vals) +self._draw_flags(subwindow, 0, 4, left_width, vals) if self._message: - self.addstr(height - 1, 0, self._message, *self._message_attr) + subwindow.addstr(0, subwindow.height - 1, self._message, *self._message_attr) elif not self.is_paused(): controller = nyx.controller.get_controller() - self.addstr(height - 1, 0, 'page %i / %i - m: menu, p: pause, h: page help, q: quit' % (controller.get_page() + 1, controller.get_page_count())) + subwindow.addstr(0, subwindow.height - 1, 'page %i / %i - m: menu, p: pause, h: page help, q: quit' % (controller.get_page() + 1, controller.get_page_count())) else: - self.addstr(height - 1, 0, 'Paused', HIGHLIGHT) + subwindow.addstr(0, subwindow.height - 1, 'Paused', HIGHLIGHT) - def _draw_platform_section(self, x, y, width, vals): + def _draw_platform_section(self, subwindow, x, y, width, vals): """ Section providing the user's hostname, platform, and version information... @@ -222,26 +222,26 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread): initial_x, space_left = x, min(width, 40) -x = self.addstr(y, x, vals.format('nyx - {hostname}', space_left)) +x = subwindow.addstr(x, y, vals.format('nyx - {hostname}', space_left)) space_left -= x - initial_x if space_left >= 10: - self.addstr(y, x, ' (%s)' % vals.format('{platform}', space_left - 3)) + subwindow.addstr(x, y, ' (%s)' % vals.format('{platform}', space_left - 3)) x, space_left =
[tor-commits] [translation/bridgedb] Update translations for bridgedb
commit 164c75bf12c16affa8b97e75dc6651a7a1c9d9e8 Author: Translation commit botDate: Mon Apr 18 10:15:03 2016 + Update translations for bridgedb --- lt/LC_MESSAGES/bridgedb.po | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lt/LC_MESSAGES/bridgedb.po b/lt/LC_MESSAGES/bridgedb.po index 8b91eab..e48b792 100644 --- a/lt/LC_MESSAGES/bridgedb.po +++ b/lt/LC_MESSAGES/bridgedb.po @@ -3,7 +3,8 @@ # This file is distributed under the same license as the BridgeDB project. # # Translators: -# AG , 2016 +# Aiste G , 2016 +# Aiste G , 2016 # Moo, 2015 # Saule Papeckyte , 2015 # Edgaras7 , 2014 @@ -13,8 +14,8 @@ msgstr "" "Project-Id-Version: The Tor Project\n" "Report-Msgid-Bugs-To: 'https://trac.torproject.org/projects/tor/newticket?component=BridgeDB=bridgedb-reported,msgid=isis,sysrqb=isis'\n" "POT-Creation-Date: 2015-07-25 03:40+\n" -"PO-Revision-Date: 2016-03-21 16:27+\n" -"Last-Translator: AG \n" +"PO-Revision-Date: 2016-04-18 10:05+\n" +"Last-Translator: Aiste G \n" "Language-Team: Lithuanian (http://www.transifex.com/otf/torproject/language/lt/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -48,7 +49,7 @@ msgstr "Šaltinio Kodas" #: bridgedb/https/templates/base.html:85 msgid "Changelog" -msgstr "" +msgstr "Keitimų žurnalas" #: bridgedb/https/templates/base.html:88 msgid "Contact" ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [translation/tor_animation] Update translations for tor_animation
commit e30f5fc73a473dae0b58c78969a797614a3cb97e Author: Translation commit botDate: Mon Apr 18 08:46:24 2016 + Update translations for tor_animation --- zh_HK.srt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zh_HK.srt b/zh_HK.srt index e1753c1..0695a83 100644 --- a/zh_HK.srt +++ b/zh_HK.srt @@ -149,5 +149,5 @@ Toræ´è¥è·¯ç±å°±æ´å¼· 35 00:02:02,000 --> 00:02:07,000 ä¸è¼ååç¨Toræ´è¥è·¯ç±ï¼æè -çéä¸åè½åé»å¦ï¼ +çéä¸åè½åç«å¦ï¼ ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [translation/abouttor-homepage_completed] Update translations for abouttor-homepage_completed
commit 6fe0597da87ae2b647ca9042bdfe95ab84d0ab09 Author: Translation commit botDate: Mon Apr 18 08:46:04 2016 + Update translations for abouttor-homepage_completed --- zh_HK/aboutTor.dtd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zh_HK/aboutTor.dtd b/zh_HK/aboutTor.dtd index 8fb0e11..46e7ab8 100644 --- a/zh_HK/aboutTor.dtd +++ b/zh_HK/aboutTor.dtd @@ -37,7 +37,7 @@ https://www.torproject.org/download/download.html.en#warning;> - + https://www.torproject.org/docs/tor-doc-relay.html.en;> https://www.torproject.org/getinvolved/volunteer.html.en;> ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [translation/tor_animation_completed] Update translations for tor_animation_completed
commit c2f93884f0d490898547a4d530bd528091641c79 Author: Translation commit botDate: Mon Apr 18 08:46:27 2016 + Update translations for tor_animation_completed --- zh_HK.srt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zh_HK.srt b/zh_HK.srt index e1753c1..0695a83 100644 --- a/zh_HK.srt +++ b/zh_HK.srt @@ -149,5 +149,5 @@ Toræ´è¥è·¯ç±å°±æ´å¼· 35 00:02:02,000 --> 00:02:07,000 ä¸è¼ååç¨Toræ´è¥è·¯ç±ï¼æè -çéä¸åè½åé»å¦ï¼ +çéä¸åè½åç«å¦ï¼ ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [translation/tor-launcher-properties_completed] Update translations for tor-launcher-properties_completed
commit 3e4a6ceea90e3110abbd0050791716e5ffc52879 Author: Translation commit botDate: Mon Apr 18 08:45:47 2016 + Update translations for tor-launcher-properties_completed --- zh_HK/torlauncher.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zh_HK/torlauncher.properties b/zh_HK/torlauncher.properties index d9413b0..0a84bcf 100644 --- a/zh_HK/torlauncher.properties +++ b/zh_HK/torlauncher.properties @@ -44,8 +44,8 @@ torlauncher.bootstrapStatus.handshake_dir=æ£å¨å»ºç«å å¯å ç®éé£ç· torlauncher.bootstrapStatus.requesting_status=æ£å¨åå¾ç¶²çµ¡çæ torlauncher.bootstrapStatus.loading_status=æ£å¨è¼å ¥ç¶²çµ¡çæ torlauncher.bootstrapStatus.loading_keys=æ£å¨è¼å ¥ææ¬æè -torlauncher.bootstrapStatus.requesting_descriptors=æ£å¨ç´¢åè½åé»è³è¨ -torlauncher.bootstrapStatus.loading_descriptors=æ£å¨è¼å ¥è½åé»è³è¨ +torlauncher.bootstrapStatus.requesting_descriptors=æ£å¨ç´¢åè½åç«è³è¨ +torlauncher.bootstrapStatus.loading_descriptors=æ£å¨è¼å ¥è½åç«è³è¨ torlauncher.bootstrapStatus.conn_or=æ£é£æ¥å°Toræ´è¥è·¯ç±ç¶²çµ¡ torlauncher.bootstrapStatus.handshake_or=æ£å¨å»ºç«Toræ´è¥è·¯ç±ç·è·¯ torlauncher.bootstrapStatus.done=å·²é£æ¥å°Toræ´è¥è·¯ç±ç¶²çµ¡ï¼ ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [translation/tor-launcher-properties] Update translations for tor-launcher-properties
commit 7af0896634af7f62c4980642f19d4a67fff22b0f Author: Translation commit botDate: Mon Apr 18 08:45:44 2016 + Update translations for tor-launcher-properties --- zh_HK/torlauncher.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zh_HK/torlauncher.properties b/zh_HK/torlauncher.properties index d9413b0..0a84bcf 100644 --- a/zh_HK/torlauncher.properties +++ b/zh_HK/torlauncher.properties @@ -44,8 +44,8 @@ torlauncher.bootstrapStatus.handshake_dir=æ£å¨å»ºç«å å¯å ç®éé£ç· torlauncher.bootstrapStatus.requesting_status=æ£å¨åå¾ç¶²çµ¡çæ torlauncher.bootstrapStatus.loading_status=æ£å¨è¼å ¥ç¶²çµ¡çæ torlauncher.bootstrapStatus.loading_keys=æ£å¨è¼å ¥ææ¬æè -torlauncher.bootstrapStatus.requesting_descriptors=æ£å¨ç´¢åè½åé»è³è¨ -torlauncher.bootstrapStatus.loading_descriptors=æ£å¨è¼å ¥è½åé»è³è¨ +torlauncher.bootstrapStatus.requesting_descriptors=æ£å¨ç´¢åè½åç«è³è¨ +torlauncher.bootstrapStatus.loading_descriptors=æ£å¨è¼å ¥è½åç«è³è¨ torlauncher.bootstrapStatus.conn_or=æ£é£æ¥å°Toræ´è¥è·¯ç±ç¶²çµ¡ torlauncher.bootstrapStatus.handshake_or=æ£å¨å»ºç«Toræ´è¥è·¯ç±ç·è·¯ torlauncher.bootstrapStatus.done=å·²é£æ¥å°Toræ´è¥è·¯ç±ç¶²çµ¡ï¼ ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [translation/torbutton-torbuttonproperties] Update translations for torbutton-torbuttonproperties
commit 49a0c53354727575ee66c91cddb7a7a74df12919 Author: Translation commit botDate: Mon Apr 18 08:46:12 2016 + Update translations for torbutton-torbuttonproperties --- zh_HK/torbutton.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zh_HK/torbutton.properties b/zh_HK/torbutton.properties index bef0787..731bd8a 100644 --- a/zh_HK/torbutton.properties +++ b/zh_HK/torbutton.properties @@ -4,7 +4,7 @@ torbutton.circuit_display.internet = äºè¯ç¶² torbutton.circuit_display.ip_unknown = æªç¥å IP torbutton.circuit_display.onion_site = æ´è¥ç¶² torbutton.circuit_display.this_browser = æ¤çè¦½å¨ -torbutton.circuit_display.relay = è½åé» +torbutton.circuit_display.relay = è½åç« torbutton.circuit_display.tor_bridge = æ©æ¥å¨ torbutton.circuit_display.unknown_country = ä¸æå家 torbutton.content_sizer.margin_tooltip = Toræ´è¥è·¯ç±ç覽å¨ç¹æå°è¦çªéæ¡å é度åé«åº¦éæ°è¨å®ï¼ä»¥ä½¿ä½ å ç覽å¨çæ è³è¨çåæ´çºæ®éï¼å¦æ¤å¯æ¸å°ä½ å 網絡活å被èå¥ä¸¦è¿½è¹¤å å¯è½æ§ã ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [translation/abouttor-homepage] Update translations for abouttor-homepage
commit d08d71e1da827fabf8561bf83fd9e39a37ff5322 Author: Translation commit botDate: Mon Apr 18 08:46:01 2016 + Update translations for abouttor-homepage --- zh_HK/aboutTor.dtd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zh_HK/aboutTor.dtd b/zh_HK/aboutTor.dtd index 8fb0e11..46e7ab8 100644 --- a/zh_HK/aboutTor.dtd +++ b/zh_HK/aboutTor.dtd @@ -37,7 +37,7 @@ https://www.torproject.org/download/download.html.en#warning;> - + https://www.torproject.org/docs/tor-doc-relay.html.en;> https://www.torproject.org/getinvolved/volunteer.html.en;> ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [translation/tor-launcher-network-settings_completed] Update translations for tor-launcher-network-settings_completed
commit 8d3328f36d9fbaa39b87dda54f6e1fe9cd0fdd75 Author: Translation commit botDate: Mon Apr 18 08:45:55 2016 + Update translations for tor-launcher-network-settings_completed --- zh_HK/network-settings.dtd | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/zh_HK/network-settings.dtd b/zh_HK/network-settings.dtd index 949b5a6..2bd62e6 100644 --- a/zh_HK/network-settings.dtd +++ b/zh_HK/network-settings.dtd @@ -59,12 +59,12 @@ - + - - + + https://bridges.torproject.org;> ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [translation/tor-launcher-network-settings] Update translations for tor-launcher-network-settings
commit 36277e94f86785dfc0c6d5616e944f5ab3e7f284 Author: Translation commit botDate: Mon Apr 18 08:45:52 2016 + Update translations for tor-launcher-network-settings --- zh_HK/network-settings.dtd | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/zh_HK/network-settings.dtd b/zh_HK/network-settings.dtd index 949b5a6..2bd62e6 100644 --- a/zh_HK/network-settings.dtd +++ b/zh_HK/network-settings.dtd @@ -59,12 +59,12 @@ - + - - + + https://bridges.torproject.org;> ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [translation/torcheck_completed] Update translations for torcheck_completed
commit 839c997bc5ba3d3d503cc82eb8ff97a848bdcdd9 Author: Translation commit botDate: Mon Apr 18 08:45:17 2016 + Update translations for torcheck_completed --- zh_HK/torcheck.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/zh_HK/torcheck.po b/zh_HK/torcheck.po index c2ede27..ca4ae34 100644 --- a/zh_HK/torcheck.po +++ b/zh_HK/torcheck.po @@ -12,7 +12,7 @@ msgid "" msgstr "" "Project-Id-Version: The Tor Project\n" "POT-Creation-Date: 2012-02-16 20:28+PDT\n" -"PO-Revision-Date: 2016-04-17 07:46+\n" +"PO-Revision-Date: 2016-04-18 08:26+\n" "Last-Translator: 大åæ´è¥\n" "Language-Team: Chinese (Hong Kong) (http://www.transifex.com/otf/torproject/language/zh_HK/)\n" "MIME-Version: 1.0\n" @@ -67,7 +67,7 @@ msgid "This page is also available in the following languages:" msgstr "æ¬é é¢ä¹æ以ä¸èªè¨çæ¬ï¼" msgid "For more information about this exit relay, see:" -msgstr "éæ¼æ¤åºå£è½åé»å æ´å¤è³è¨ï¼è«åé±ï¼" +msgstr "éæ¼æ¤åºå£è½åç«å æ´å¤è³è¨ï¼è«åé±ï¼" msgid "" "The Tor Project is a US 501(c)(3) non-profit dedicated to the research, " @@ -102,7 +102,7 @@ msgid "However, it does not appear to be Tor Browser." msgstr "ç¶èï¼éä¼¼ä¹ä¸¦éToræ´è¥è·¯ç±ç覽å¨ã" msgid "Run a Relay" -msgstr "æ¶è¨ä¸åè½åé»" +msgstr "æ¶è¨ä¸åè½åç«" msgid "Stay Anonymous" msgstr "ä¿æå¿å" ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [translation/torcheck] Update translations for torcheck
commit f438639aaef526946a3a95da79ca0e624e972179 Author: Translation commit botDate: Mon Apr 18 08:45:14 2016 + Update translations for torcheck --- zh_HK/torcheck.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/zh_HK/torcheck.po b/zh_HK/torcheck.po index c2ede27..ca4ae34 100644 --- a/zh_HK/torcheck.po +++ b/zh_HK/torcheck.po @@ -12,7 +12,7 @@ msgid "" msgstr "" "Project-Id-Version: The Tor Project\n" "POT-Creation-Date: 2012-02-16 20:28+PDT\n" -"PO-Revision-Date: 2016-04-17 07:46+\n" +"PO-Revision-Date: 2016-04-18 08:26+\n" "Last-Translator: 大åæ´è¥\n" "Language-Team: Chinese (Hong Kong) (http://www.transifex.com/otf/torproject/language/zh_HK/)\n" "MIME-Version: 1.0\n" @@ -67,7 +67,7 @@ msgid "This page is also available in the following languages:" msgstr "æ¬é é¢ä¹æ以ä¸èªè¨çæ¬ï¼" msgid "For more information about this exit relay, see:" -msgstr "éæ¼æ¤åºå£è½åé»å æ´å¤è³è¨ï¼è«åé±ï¼" +msgstr "éæ¼æ¤åºå£è½åç«å æ´å¤è³è¨ï¼è«åé±ï¼" msgid "" "The Tor Project is a US 501(c)(3) non-profit dedicated to the research, " @@ -102,7 +102,7 @@ msgid "However, it does not appear to be Tor Browser." msgstr "ç¶èï¼éä¼¼ä¹ä¸¦éToræ´è¥è·¯ç±ç覽å¨ã" msgid "Run a Relay" -msgstr "æ¶è¨ä¸åè½åé»" +msgstr "æ¶è¨ä¸åè½åç«" msgid "Stay Anonymous" msgstr "ä¿æå¿å" ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [translation/bridgedb_completed] Update translations for bridgedb_completed
commit 6fab195aa319365fbd0e7350789fb83912e886c7 Author: Translation commit botDate: Mon Apr 18 08:45:09 2016 + Update translations for bridgedb_completed --- zh_HK/LC_MESSAGES/bridgedb.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zh_HK/LC_MESSAGES/bridgedb.po b/zh_HK/LC_MESSAGES/bridgedb.po index 766434a..052ad76 100644 --- a/zh_HK/LC_MESSAGES/bridgedb.po +++ b/zh_HK/LC_MESSAGES/bridgedb.po @@ -14,7 +14,7 @@ msgstr "" "Project-Id-Version: The Tor Project\n" "Report-Msgid-Bugs-To: 'https://trac.torproject.org/projects/tor/newticket?component=BridgeDB=bridgedb-reported,msgid=isis,sysrqb=isis'\n" "POT-Creation-Date: 2015-07-25 03:40+\n" -"PO-Revision-Date: 2016-04-17 07:48+\n" +"PO-Revision-Date: 2016-04-18 08:27+\n" "Last-Translator: 大åæ´è¥\n" "Language-Team: Chinese (Hong Kong) (http://www.transifex.com/otf/torproject/language/zh_HK/)\n" "MIME-Version: 1.0\n" @@ -260,7 +260,7 @@ msgstr "å©ä¿æ©æ¥ï¼" #: bridgedb/strings.py:102 #, python-format msgid "%s Bridges %s are Tor relays that help you circumvent censorship." -msgstr "%sæ©æ¥å¨%sä¿Toræ´è¥è·¯ç±è½åé»ï¼å¯å¹«ä½ è¦é¿å¯©æ¥ã" +msgstr "%sæ©æ¥å¨%sä¿Toræ´è¥è·¯ç±è½åç«ï¼å¯å¹«ä½ è¦é¿å¯©æ¥ã" #: bridgedb/strings.py:107 msgid "I need an alternative way of getting bridges!" ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [translation/bridgedb] Update translations for bridgedb
commit 1bcc26ff8349eeeb7f121c1bb479182e7609e587 Author: Translation commit botDate: Mon Apr 18 08:45:04 2016 + Update translations for bridgedb --- zh_HK/LC_MESSAGES/bridgedb.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zh_HK/LC_MESSAGES/bridgedb.po b/zh_HK/LC_MESSAGES/bridgedb.po index 766434a..052ad76 100644 --- a/zh_HK/LC_MESSAGES/bridgedb.po +++ b/zh_HK/LC_MESSAGES/bridgedb.po @@ -14,7 +14,7 @@ msgstr "" "Project-Id-Version: The Tor Project\n" "Report-Msgid-Bugs-To: 'https://trac.torproject.org/projects/tor/newticket?component=BridgeDB=bridgedb-reported,msgid=isis,sysrqb=isis'\n" "POT-Creation-Date: 2015-07-25 03:40+\n" -"PO-Revision-Date: 2016-04-17 07:48+\n" +"PO-Revision-Date: 2016-04-18 08:27+\n" "Last-Translator: 大åæ´è¥\n" "Language-Team: Chinese (Hong Kong) (http://www.transifex.com/otf/torproject/language/zh_HK/)\n" "MIME-Version: 1.0\n" @@ -260,7 +260,7 @@ msgstr "å©ä¿æ©æ¥ï¼" #: bridgedb/strings.py:102 #, python-format msgid "%s Bridges %s are Tor relays that help you circumvent censorship." -msgstr "%sæ©æ¥å¨%sä¿Toræ´è¥è·¯ç±è½åé»ï¼å¯å¹«ä½ è¦é¿å¯©æ¥ã" +msgstr "%sæ©æ¥å¨%sä¿Toræ´è¥è·¯ç±è½åç«ï¼å¯å¹«ä½ è¦é¿å¯©æ¥ã" #: bridgedb/strings.py:107 msgid "I need an alternative way of getting bridges!" ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [webwml/master] move email farther down the page (suggested by kate)
commit 49d02e090ad00a003a294fc311035a335ab321b4 Author: Roger DingledineDate: Mon Apr 18 02:10:37 2016 -0400 move email farther down the page (suggested by kate) --- about/en/contact.wml | 40 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/about/en/contact.wml b/about/en/contact.wml index 465fd48..277ea9f 100644 --- a/about/en/contact.wml +++ b/about/en/contact.wml @@ -14,9 +14,9 @@ Tor: Contact Support -Email IRC Twitter +Email Mailing Address Security Issues @@ -59,25 +59,6 @@ If you find your answer, please stick around to contribute back and help others who were once in your position. - -Email -If you have Tor questions, please try to help yourself via the -above support venues. Please don't use these contact addresses -for helpdesk or user requests we all get too much mail and -we won't be able to help you there. - - - donati...@torproject.org is for questions and comments about getting money to the developers. More - donations means more - Tor. We're happy to help think about creative ways for you - to contribute. - exec...@torproject.org is for questions and comments about - Tor the non-profit corporation: trademark questions, affiliation - and coordination, major gifts, contract inquiries, licensing and - certification, etc. - - IRC Tor users and developers can also be found in the following channels on + +Email +If you have Tor questions, please try to help yourself via the +above support venues. Please don't use these contact addresses +for helpdesk or user requests we all get too much mail and +we won't be able to help you there. + + + donati...@torproject.org is for questions and comments about getting money to the developers. More + donations means more + Tor. We're happy to help think about creative ways for you + to contribute. + exec...@torproject.org is for questions and comments about + Tor the non-profit corporation: trademark questions, affiliation + and coordination, major gifts, contract inquiries, licensing and + certification, etc. + + Mailing Address Should you need to reach us via old reliable mail, our mailing ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [webwml/master] kate points out that press is already at the top of the page
commit 3f0eaa62f54bdd0964e7d7b9697a46bae836fc2b Author: Roger DingledineDate: Mon Apr 18 02:08:35 2016 -0400 kate points out that press is already at the top of the page --- about/en/contact.wml | 1 - 1 file changed, 1 deletion(-) diff --git a/about/en/contact.wml b/about/en/contact.wml index 61d6716..465fd48 100644 --- a/about/en/contact.wml +++ b/about/en/contact.wml @@ -72,7 +72,6 @@ donations means more Tor. We're happy to help think about creative ways for you to contribute. - pr...@torproject.org is for press/media. exec...@torproject.org is for questions and comments about Tor the non-profit corporation: trademark questions, affiliation and coordination, major gifts, contract inquiries, licensing and ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits