aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/vk/tracking
diff options
context:
space:
mode:
Diffstat (limited to 'vk/tracking')
-rw-r--r--vk/tracking/__init__.py5
-rw-r--r--vk/tracking/db/backend/__init__.py6
-rw-r--r--vk/tracking/db/backend/log.py16
-rw-r--r--vk/tracking/sessions.py120
-rw-r--r--vk/tracking/status.py82
5 files changed, 151 insertions, 78 deletions
diff --git a/vk/tracking/__init__.py b/vk/tracking/__init__.py
index 73133d8..51c35cd 100644
--- a/vk/tracking/__init__.py
+++ b/vk/tracking/__init__.py
@@ -2,4 +2,7 @@
# This file is licensed under the terms of the MIT License.
# See LICENSE.txt for details.
-__all__ = 'sessions', 'status',
+__all__ = (
+ 'sessions',
+ 'status',
+)
diff --git a/vk/tracking/db/backend/__init__.py b/vk/tracking/db/backend/__init__.py
index 58b5a9a..5b2398b 100644
--- a/vk/tracking/db/backend/__init__.py
+++ b/vk/tracking/db/backend/__init__.py
@@ -5,4 +5,8 @@
from . import csv, log, null
-__all__ = 'csv', 'log', 'null',
+__all__ = (
+ 'csv',
+ 'log',
+ 'null',
+)
diff --git a/vk/tracking/db/backend/log.py b/vk/tracking/db/backend/log.py
index efdc664..11fc328 100644
--- a/vk/tracking/db/backend/log.py
+++ b/vk/tracking/db/backend/log.py
@@ -13,9 +13,11 @@ class Writer(meta.Writer):
self._logger = logging.getLogger(__file__)
self._logger.setLevel(logging.INFO)
handler = logging.StreamHandler(fd)
- handler.setFormatter(logging.Formatter(
- fmt='[%(asctime)s] %(message)s',
- datefmt='%Y-%m-%d %H:%M:%S%z'))
+ handler.setFormatter(
+ logging.Formatter(
+ fmt='[%(asctime)s] %(message)s', datefmt='%Y-%m-%d %H:%M:%S%z'
+ )
+ )
self._logger.addHandler(handler)
self._reset_last_notification()
@@ -86,7 +88,8 @@ class Writer(meta.Writer):
return '{} was last seen at {} using {}.'.format(
Writer._format_user(user),
user.get_last_seen_time_local(),
- user.get_last_seen_platform().get_descr_text())
+ user.get_last_seen_platform().get_descr_text(),
+ )
@staticmethod
def _format_user_went_online(user):
@@ -98,4 +101,7 @@ class Writer(meta.Writer):
@staticmethod
def _format_another_connection_error(e):
- return 'Encountered a connection error which looks like the previous one: ' + str(e)
+ return (
+ 'Encountered a connection error which looks like the previous one: '
+ + str(e)
+ )
diff --git a/vk/tracking/sessions.py b/vk/tracking/sessions.py
index 4b6fd66..4622c2e 100644
--- a/vk/tracking/sessions.py
+++ b/vk/tracking/sessions.py
@@ -339,10 +339,12 @@ class OutputSinkPlot(OutputSinkOnlineSessions):
@staticmethod
def _extract_values(durations):
- return (OutputSinkPlot._duration_to_seconds(duration) for duration in durations.values())
+ return (
+ OutputSinkPlot._duration_to_seconds(duration)
+ for duration in durations.values()
+ )
- def process_database(
- self, group_by, db_reader, time_from=None, time_to=None):
+ def process_database(self, group_by, db_reader, time_from=None, time_to=None):
durations = group_by.group(db_reader, time_from, time_to)
@@ -350,8 +352,9 @@ class OutputSinkPlot(OutputSinkOnlineSessions):
bar_chart.set_title(OutputSinkPlot.TITLE)
bar_chart.enable_grid_for_values()
bar_chart.only_integer_values()
- bar_chart.set_property(bar_chart.get_values_labels(),
- fontsize='small', rotation=30)
+ bar_chart.set_property(
+ bar_chart.get_values_labels(), fontsize='small', rotation=30
+ )
bar_chart.set_value_label_formatter(self._format_duration)
labels = tuple(self._extract_labels(group_by, durations))
@@ -363,9 +366,8 @@ class OutputSinkPlot(OutputSinkOnlineSessions):
else:
bar_height = bar_chart.THICK_BAR_HEIGHT
- bars = bar_chart.plot_bars(
- labels, durations, bar_height=bar_height)
- bar_chart.set_property(bars, alpha=.33)
+ bars = bar_chart.plot_bars(labels, durations, bar_height=bar_height)
+ bar_chart.set_property(bars, alpha=0.33)
if self._fd is sys.stdout:
bar_chart.show()
@@ -426,8 +428,7 @@ def _parse_date_range_limit(s):
return dt.replace(tzinfo=timezone.utc)
except ValueError:
msg = 'invalid date range limit (must be in the \'{}\' format): {}'
- raise argparse.ArgumentTypeError(
- msg.format(_DATE_RANGE_LIMIT_FORMAT, s))
+ raise argparse.ArgumentTypeError(msg.format(_DATE_RANGE_LIMIT_FORMAT, s))
def _parse_args(args=None):
@@ -435,44 +436,78 @@ def _parse_args(args=None):
args = sys.argv[1:]
parser = argparse.ArgumentParser(
- description='View/visualize the amount of time people spend online.')
+ description='View/visualize the amount of time people spend online.'
+ )
vk.version.add_to_arg_parser(parser)
- parser.add_argument('db_path', metavar='input', nargs='?',
- help='database file path (standard input by default)')
- parser.add_argument('out_path', metavar='output', nargs='?',
- help='output file path (standard output by default)')
- parser.add_argument('-g', '--group-by',
- type=_parse_group_by,
- choices=GroupBy,
- default=GroupBy.USER,
- help='group online sessions by user/date/etc.')
- parser.add_argument('-i', '--input-format', dest='db_fmt',
- type=_parse_database_format,
- default=DatabaseFormat.CSV,
- choices=DatabaseFormat,
- help='specify database format')
- parser.add_argument('-o', '--output-format', dest='out_fmt',
- type=_parse_output_format,
- choices=OutputFormat,
- default=OutputFormat.CSV,
- help='specify output format')
- parser.add_argument('-a', '--from', dest='time_from',
- type=_parse_date_range_limit, default=None,
- help='discard online activity prior to this moment')
- parser.add_argument('-b', '--to', dest='time_to',
- type=_parse_date_range_limit, default=None,
- help='discard online activity after this moment')
+ parser.add_argument(
+ 'db_path',
+ metavar='input',
+ nargs='?',
+ help='database file path (standard input by default)',
+ )
+ parser.add_argument(
+ 'out_path',
+ metavar='output',
+ nargs='?',
+ help='output file path (standard output by default)',
+ )
+ parser.add_argument(
+ '-g',
+ '--group-by',
+ type=_parse_group_by,
+ choices=GroupBy,
+ default=GroupBy.USER,
+ help='group online sessions by user/date/etc.',
+ )
+ parser.add_argument(
+ '-i',
+ '--input-format',
+ dest='db_fmt',
+ type=_parse_database_format,
+ default=DatabaseFormat.CSV,
+ choices=DatabaseFormat,
+ help='specify database format',
+ )
+ parser.add_argument(
+ '-o',
+ '--output-format',
+ dest='out_fmt',
+ type=_parse_output_format,
+ choices=OutputFormat,
+ default=OutputFormat.CSV,
+ help='specify output format',
+ )
+ parser.add_argument(
+ '-a',
+ '--from',
+ dest='time_from',
+ type=_parse_date_range_limit,
+ default=None,
+ help='discard online activity prior to this moment',
+ )
+ parser.add_argument(
+ '-b',
+ '--to',
+ dest='time_to',
+ type=_parse_date_range_limit,
+ default=None,
+ help='discard online activity after this moment',
+ )
return parser.parse_args(args)
def process_online_sessions(
- db_path=None, db_fmt=DatabaseFormat.CSV,
- out_path=None, out_fmt=OutputFormat.CSV,
- group_by=GroupBy.USER,
- time_from=None, time_to=None):
+ db_path=None,
+ db_fmt=DatabaseFormat.CSV,
+ out_path=None,
+ out_fmt=OutputFormat.CSV,
+ group_by=GroupBy.USER,
+ time_from=None,
+ time_to=None,
+):
if time_from is not None and time_to is not None:
if time_from > time_to:
@@ -483,9 +518,8 @@ def process_online_sessions(
with out_fmt.open_file(out_path) as out_fd:
out_sink = out_fmt.create_sink(out_fd)
out_sink.process_database(
- group_by, db_reader,
- time_from=time_from,
- time_to=time_to)
+ group_by, db_reader, time_from=time_from, time_to=time_to
+ )
def main(args=None):
diff --git a/vk/tracking/status.py b/vk/tracking/status.py
index 0dd5e42..42f0adb 100644
--- a/vk/tracking/status.py
+++ b/vk/tracking/status.py
@@ -52,11 +52,16 @@ class StatusTracker:
if not isinstance(fn, Callable):
raise TypeError()
- _USER_FIELDS = UserField.DOMAIN, UserField.ONLINE, UserField.LAST_SEEN,
+ _USER_FIELDS = (
+ UserField.DOMAIN,
+ UserField.ONLINE,
+ UserField.LAST_SEEN,
+ )
def _query_status(self, uids):
- user_list = self._api.users_get(uids, self._USER_FIELDS,
- deactivated_users=False)
+ user_list = self._api.users_get(
+ uids, self._USER_FIELDS, deactivated_users=False
+ )
return {user.get_uid(): user for user in user_list}
def _notify_status(self, user):
@@ -128,13 +133,11 @@ class StatusTracker:
def _handle_sigint():
# Python doesn't raise KeyboardInterrupt in case a real SIGINT is sent
# from outside, surprisingly.
- return StatusTracker._handle_signal(signal.SIGINT,
- StatusTracker._stop_looping)
+ return StatusTracker._handle_signal(signal.SIGINT, StatusTracker._stop_looping)
@staticmethod
def _handle_sigterm():
- return StatusTracker._handle_signal(signal.SIGTERM,
- StatusTracker._stop_looping)
+ return StatusTracker._handle_signal(signal.SIGTERM, StatusTracker._stop_looping)
def loop(self, uids):
with self._handle_sigint(), self._handle_sigterm():
@@ -169,35 +172,58 @@ def _parse_args(args=None):
if args is None:
args = sys.argv[1:]
- parser = argparse.ArgumentParser(
- description='Track when people go online/offline.')
+ parser = argparse.ArgumentParser(description='Track when people go online/offline.')
vk.version.add_to_arg_parser(parser)
- parser.add_argument('uids', metavar='UID', nargs='+',
- help='user IDs or "screen names"')
- parser.add_argument('-t', '--timeout', metavar='SECONDS',
- type=_parse_positive_integer,
- default=DEFAULT_TIMEOUT,
- help='set refresh interval')
- parser.add_argument('-O', '--only-once', action='store_true',
- help='query the status only once and exit')
- parser.add_argument('-l', '--log', metavar='PATH', dest='log_path',
- help='set log file path (standard output by default)')
- parser.add_argument('-f', '--format', dest='db_fmt',
- type=_parse_database_format,
- choices=DatabaseFormat,
- default=DEFAULT_DB_FORMAT,
- help='specify database format')
- parser.add_argument('-o', '--output', metavar='PATH', dest='db_path',
- help='set database file path')
+ parser.add_argument(
+ 'uids', metavar='UID', nargs='+', help='user IDs or "screen names"'
+ )
+ parser.add_argument(
+ '-t',
+ '--timeout',
+ metavar='SECONDS',
+ type=_parse_positive_integer,
+ default=DEFAULT_TIMEOUT,
+ help='set refresh interval',
+ )
+ parser.add_argument(
+ '-O',
+ '--only-once',
+ action='store_true',
+ help='query the status only once and exit',
+ )
+ parser.add_argument(
+ '-l',
+ '--log',
+ metavar='PATH',
+ dest='log_path',
+ help='set log file path (standard output by default)',
+ )
+ parser.add_argument(
+ '-f',
+ '--format',
+ dest='db_fmt',
+ type=_parse_database_format,
+ choices=DatabaseFormat,
+ default=DEFAULT_DB_FORMAT,
+ help='specify database format',
+ )
+ parser.add_argument(
+ '-o', '--output', metavar='PATH', dest='db_path', help='set database file path'
+ )
return parser.parse_args(args)
def track_status(
- uids, timeout=DEFAULT_TIMEOUT, log_path=None,
- db_path=None, db_fmt=DEFAULT_DB_FORMAT, only_once=False):
+ uids,
+ timeout=DEFAULT_TIMEOUT,
+ log_path=None,
+ db_path=None,
+ db_fmt=DEFAULT_DB_FORMAT,
+ only_once=False,
+):
api = API()
tracker = StatusTracker(api, timeout)