aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--.pylintrc55
-rw-r--r--README.md24
-rw-r--r--bin/mutual_friends.py6
-rw-r--r--bin/online_sessions.py48
-rw-r--r--bin/track_status.py18
-rw-r--r--vk/last_seen.py30
-rw-r--r--vk/platform.py20
-rw-r--r--vk/tracking/db/record.py6
-rw-r--r--vk/tracking/db/timestamp.py30
-rw-r--r--vk/tracking/online_sessions.py24
-rw-r--r--vk/tracking/status_tracker.py34
-rw-r--r--vk/user.py32
12 files changed, 178 insertions, 149 deletions
diff --git a/.pylintrc b/.pylintrc
index 86cac01..4cb9bbf 100644
--- a/.pylintrc
+++ b/.pylintrc
@@ -1,31 +1,36 @@
[MESSAGES CONTROL]
-disable=missing-docstring,too-many-public-methods,too-few-public-methods,multiple-imports,duplicate-code
+#disable=old-ne-operator,filter-builtin-not-iterating,nonzero-method,long-builtin,unpacking-in-except,backtick,suppressed-message,setslice-method,round-builtin,coerce-builtin,input-builtin,raising-string,raw_input-builtin,apply-builtin,delslice-method,useless-suppression,hex-method,zip-builtin-not-iterating,range-builtin-not-iterating,intern-builtin,old-octal-literal,xrange-builtin,no-absolute-import,cmp-builtin,reduce-builtin,next-method-called,getslice-method,oct-method,reload-builtin,dict-view-method,file-builtin,long-suffix,parameter-unpacking,dict-iter-method,cmp-method,old-division,using-cmp-argument,buffer-builtin,old-raise-syntax,indexing-exception,unicode-builtin,unichr-builtin,coerce-method,basestring-builtin,map-builtin-not-iterating,metaclass-assignment,print-statement,import-star-module-level,standarderror-builtin,execfile-builtin
+disable=duplicate-code,missing-docstring,multiple-imports,too-many-public-methods,too-few-public-methods
[BASIC]
+#bad-functions=map,filter
bad-functions=
-good-names=i,j,k
-bad-names=
-name-group=
-include-naming-hint=no
-inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
-inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$
-method-rgx=[a-z_][a-z0-9_]{2,30}$
-method-name-hint=[a-z_][a-z0-9_]{2,30}$
-class-rgx=[A-Z_][a-zA-Z0-9]+$
-class-name-hint=[A-Z_][a-zA-Z0-9]+$
-attr-rgx=[a-z_][a-z0-9_]{0,30}$
-attr-name-hint=[a-z_][a-z0-9_]{0,30}$
-function-rgx=[a-z_][a-z0-9_]{2,30}$
-function-name-hint=[a-z_][a-z0-9_]{2,30}$
-module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
-module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
-class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{1,30}|(__.*__))$
-class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{1,30}|(__.*__))$
-variable-rgx=[a-z_][a-z0-9_]{0,30}$
-variable-name-hint=[a-z_][a-z0-9_]{0,30}$
-argument-rgx=[a-z_][a-z0-9_]{0,30}$
-argument-name-hint=[a-z_][a-z0-9_]{0,30}$
-no-docstring-rgx=^_
-docstring-min-length=-1
+#good-names=i,j,k,ex,Run,_
+good-names=_,e,fd,i,n
+#bad-names=foo,bar,baz,toto,tutu,tata
+#name-group=
+#include-naming-hint=no
+#class-rgx=[A-Z_][a-zA-Z0-9]+$
+#class-name-hint=[A-Z_][a-zA-Z0-9]+$
+#module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
+#module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
+#inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
+#inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$
+#variable-rgx=[a-z_][a-z0-9_]{2,30}$
+#variable-name-hint=[a-z_][a-z0-9_]{2,30}$
+#const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$
+#const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$
+#function-rgx=[a-z_][a-z0-9_]{2,30}$
+#function-name-hint=[a-z_][a-z0-9_]{2,30}$
+#attr-rgx=[a-z_][a-z0-9_]{2,30}$
+#attr-name-hint=[a-z_][a-z0-9_]{2,30}$
+#argument-rgx=[a-z_][a-z0-9_]{2,30}$
+#argument-name-hint=[a-z_][a-z0-9_]{2,30}$
+#method-rgx=[a-z_][a-z0-9_]{2,30}$
+#method-name-hint=[a-z_][a-z0-9_]{2,30}$
+#class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
+#class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
+#no-docstring-rgx=^_
+#docstring-min-length=-1
diff --git a/README.md b/README.md
index 617c5ad..4456c0e 100644
--- a/README.md
+++ b/README.md
@@ -39,6 +39,30 @@ online.
[track_status.py]: docs/track_status.md
[online_sessions.py]: docs/online_sessions.md
+Linting
+-------
+
+Requires [PyLint].
+
+ > cd
+ D:\workspace\personal\vk-scripts
+
+ > pylint vk
+ ...
+
+ > set PYTHONPATH=%CD%
+
+ > pylint bin\mutual_friends.py
+ ...
+
+ > pylint bin\online_sessions.py
+ ...
+
+ > pylint bin\track_status.py
+ ...
+
+[PyLint]: https://www.pylint.org/
+
License
-------
diff --git a/bin/mutual_friends.py b/bin/mutual_friends.py
index 8e6e584..29f92d9 100644
--- a/bin/mutual_friends.py
+++ b/bin/mutual_friends.py
@@ -70,11 +70,11 @@ class OutputFormat(Enum):
else:
raise NotImplementedError('unsupported output format: ' + str(self))
-def _parse_output_format(s):
+def _parse_output_format(src):
try:
- return OutputFormat(s)
+ return OutputFormat(src)
except ValueError:
- raise argparse.ArgumentTypeError('invalid output format: ' + s)
+ raise argparse.ArgumentTypeError('invalid output format: ' + src)
def _parse_args(args=sys.argv):
parser = argparse.ArgumentParser(
diff --git a/bin/online_sessions.py b/bin/online_sessions.py
index dc1a2ee..a42e0dd 100644
--- a/bin/online_sessions.py
+++ b/bin/online_sessions.py
@@ -145,17 +145,17 @@ class OutputWriterJSON:
raise NotImplementedError('unsupported grouping: ' + str(group_by))
return OutputWriterJSON._CONVERT_KEY[group_by](key)
- def _write(self, x):
- self._fd.write(json.dumps(x, indent=3, ensure_ascii=False))
+ def _write(self, entries):
+ self._fd.write(json.dumps(entries, indent=3, ensure_ascii=False))
self._fd.write('\n')
def process_database(self, group_by, db_reader, time_from=None, time_to=None):
- arr = []
+ entries = []
for key, duration in group_by.group(db_reader, time_from, time_to).items():
- obj = self._key_to_object(group_by, key)
- obj[self._DURATION_FIELD] = str(duration)
- arr.append(obj)
- self._write(arr)
+ entry = self._key_to_object(group_by, key)
+ entry[self._DURATION_FIELD] = str(duration)
+ entries.append(entry)
+ self._write(entries)
class BarChartBuilder:
_BAR_HEIGHT = 1.
@@ -187,9 +187,9 @@ class BarChartBuilder:
def get_value_labels(self):
return self._get_value_axis().get_ticklabels()
- def set_value_label_formatter(self, fn):
+ def set_value_label_formatter(self, handler):
from matplotlib.ticker import FuncFormatter
- self._get_value_axis().set_major_formatter(FuncFormatter(fn))
+ self._get_value_axis().set_major_formatter(FuncFormatter(handler))
def set_integer_values_only(self):
from matplotlib.ticker import MaxNLocator
@@ -289,8 +289,8 @@ class OutputWriterPlot:
return str(timedelta(seconds=seconds))
@staticmethod
- def _duration_to_seconds(td):
- return td.total_seconds()
+ def _duration_to_seconds(duration):
+ return duration.total_seconds()
@staticmethod
def _extract_labels(group_by, durations):
@@ -350,34 +350,34 @@ class OutputFormat(Enum):
def __str__(self):
return self.value
-def _parse_group_by(s):
+def _parse_group_by(src):
try:
- return GroupBy(s)
+ return GroupBy(src)
except ValueError:
- raise argparse.ArgumentTypeError('invalid "group by" value: ' + s)
+ raise argparse.ArgumentTypeError('invalid "group by" value: ' + src)
-def _parse_database_format(s):
+def _parse_database_format(src):
try:
- return DatabaseFormat(s)
+ return DatabaseFormat(src)
except ValueError:
- raise argparse.ArgumentTypeError('invalid database format: ' + s)
+ raise argparse.ArgumentTypeError('invalid database format: ' + src)
-def _parse_output_format(s):
+def _parse_output_format(src):
try:
- return OutputFormat(s)
+ return OutputFormat(src)
except ValueError:
- raise argparse.ArgumentTypeError('invalid output format: ' + s)
+ raise argparse.ArgumentTypeError('invalid output format: ' + src)
_DATE_RANGE_LIMIT_FORMAT = '%Y-%m-%dT%H:%M:%SZ'
-def _parse_date_range_limit(s):
+def _parse_date_range_limit(src):
try:
- dt = datetime.strptime(s, _DATE_RANGE_LIMIT_FORMAT)
- return dt.replace(tzinfo=timezone.utc)
+ timestamp = datetime.strptime(src, _DATE_RANGE_LIMIT_FORMAT)
+ return timestamp.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))
+ msg.format(_DATE_RANGE_LIMIT_FORMAT, src))
def _parse_args(args=sys.argv):
parser = argparse.ArgumentParser(
diff --git a/bin/track_status.py b/bin/track_status.py
index 84495f9..e59b0e1 100644
--- a/bin/track_status.py
+++ b/bin/track_status.py
@@ -12,20 +12,20 @@ from vk.tracking.db import Format as DatabaseFormat
DEFAULT_TIMEOUT = StatusTracker.DEFAULT_TIMEOUT
DEFAULT_DB_FORMAT = DatabaseFormat.CSV
-def _parse_positive_integer(s):
+def _parse_positive_integer(src):
try:
- x = int(s)
+ n = int(src)
except ValueError:
- raise argparse.ArgumentTypeError('must be a positive integer: ' + s)
- if x < 1:
- raise argparse.ArgumentTypeError('must be a positive integer: ' + s)
- return x
+ raise argparse.ArgumentTypeError('must be a positive integer: ' + src)
+ if n < 1:
+ raise argparse.ArgumentTypeError('must be a positive integer: ' + src)
+ return n
-def _parse_database_format(s):
+def _parse_database_format(src):
try:
- return DatabaseFormat(s)
+ return DatabaseFormat(src)
except ValueError:
- raise argparse.ArgumentTypeError('invalid database format: ' + s)
+ raise argparse.ArgumentTypeError('invalid database format: ' + src)
def _parse_args(args=sys.argv):
parser = argparse.ArgumentParser(
diff --git a/vk/last_seen.py b/vk/last_seen.py
index ac62d65..1753e12 100644
--- a/vk/last_seen.py
+++ b/vk/last_seen.py
@@ -11,23 +11,23 @@ from numbers import Integral, Real
from .platform import Platform
-def _parse_time(x):
- if isinstance(x, datetime):
- if x.tzinfo is None or x.tzinfo.utcoffset(x) is None:
- x = x.replace(tzinfo=timezone.utc)
- return x
- elif isinstance(x, Real) or isinstance(x, Integral):
- return datetime.fromtimestamp(x, tz=timezone.utc)
+def _parse_time(src):
+ if isinstance(src, datetime):
+ if src.tzinfo is None or src.tzinfo.utcoffset(src) is None:
+ src = src.replace(tzinfo=timezone.utc)
+ return src
+ elif isinstance(src, Real) or isinstance(src, Integral):
+ return datetime.fromtimestamp(src, tz=timezone.utc)
else:
raise TypeError()
-def _parse_platform(x):
- if x in Platform:
- return x
- if isinstance(x, str):
- return Platform.from_string(x)
+def _parse_platform(src):
+ if src in Platform:
+ return src
+ if isinstance(src, str):
+ return Platform.from_string(src)
else:
- return Platform(x)
+ return Platform(src)
class LastSeenField(Enum):
TIME = 'time'
@@ -85,8 +85,8 @@ class LastSeen(MutableMapping):
def get_time(self):
return self[LastSeenField.TIME]
- def set_time(self, t):
- self[LastSeenField.TIME] = t
+ def set_time(self, timestamp):
+ self[LastSeenField.TIME] = timestamp
def has_platform(self):
return LastSeenField.PLATFORM in self
diff --git a/vk/platform.py b/vk/platform.py
index fa1e665..26f20dc 100644
--- a/vk/platform.py
+++ b/vk/platform.py
@@ -16,26 +16,26 @@ class Platform(Enum):
WEB = 7
@staticmethod
- def from_string(s):
- return Platform(int(s))
+ def from_string(src):
+ return Platform(int(src))
def __str__(self):
return str(self.value)
@staticmethod
- def _uppercase_first_letter(s):
- m = re.search(r'\w', s)
- if m is None:
- return s
- return s[:m.start()] + m.group().upper() + s[m.end():]
+ def _uppercase_first_letter(text):
+ match = re.search(r'\w', text)
+ if match is None:
+ return text
+ return text[:match.start()] + match.group().upper() + text[match.end():]
def get_descr_header(self):
return self._uppercase_first_letter(_PLATFORM_DESCRIPTIONS[self])
def get_descr_text(self):
- s = _PLATFORM_DESCRIPTIONS[self]
- s = s.replace('unrecognized', 'an unrecognized')
- return 'the ' + s
+ descr = _PLATFORM_DESCRIPTIONS[self]
+ descr = descr.replace('unrecognized', 'an unrecognized')
+ return 'the ' + descr
def get_descr_text_capitalized(self):
return self._uppercase_first_letter(self.get_descr_text())
diff --git a/vk/tracking/db/record.py b/vk/tracking/db/record.py
index c03c3ca..6c000ab 100644
--- a/vk/tracking/db/record.py
+++ b/vk/tracking/db/record.py
@@ -38,9 +38,9 @@ class Record(MutableMapping):
def __setitem__(self, field, value):
if field is LastSeenField.TIME:
if isinstance(value, str):
- value = Timestamp.from_string(value).dt
+ value = Timestamp.from_string(value).impl
elif isinstance(value, Timestamp):
- value = value.dt
+ value = value.impl
elif isinstance(value, datetime):
pass
else:
@@ -78,7 +78,7 @@ class Record(MutableMapping):
def _update_last_seen_field(self, last_seen, field):
if field is LastSeenField.TIME:
- last_seen[field] = self[field].dt
+ last_seen[field] = self[field].impl
else:
last_seen[field] = self[field]
diff --git a/vk/tracking/db/timestamp.py b/vk/tracking/db/timestamp.py
index b2219ca..0881fb3 100644
--- a/vk/tracking/db/timestamp.py
+++ b/vk/tracking/db/timestamp.py
@@ -11,25 +11,25 @@ class Timestamp:
return datetime.utcnow()
@staticmethod
- def _is_timezone_aware(dt):
- return dt.tzinfo is not None and dt.tzinfo.utcoffset(dt) is not None
+ def _is_timezone_aware(impl):
+ return impl.tzinfo is not None and impl.tzinfo.utcoffset(impl) is not None
@staticmethod
- def _lose_timezone(dt):
- if Timestamp._is_timezone_aware(dt):
- return dt.astimezone(timezone.utc).replace(tzinfo=None)
- return dt
+ def _lose_timezone(impl):
+ if Timestamp._is_timezone_aware(impl):
+ return impl.astimezone(timezone.utc).replace(tzinfo=None)
+ return impl
- def __init__(self, dt=None):
- if dt is None:
- dt = self._new()
- dt = dt.replace(microsecond=0)
- dt = self._lose_timezone(dt)
- self.dt = dt
+ def __init__(self, impl=None):
+ if impl is None:
+ impl = self._new()
+ impl = impl.replace(microsecond=0)
+ impl = self._lose_timezone(impl)
+ self.impl = impl
@staticmethod
- def from_string(s):
- return Timestamp(datetime.strptime(s, '%Y-%m-%dT%H:%M:%SZ'))
+ def from_string(src):
+ return Timestamp(datetime.strptime(src, '%Y-%m-%dT%H:%M:%SZ'))
def __str__(self):
- return self.dt.isoformat() + 'Z'
+ return self.impl.isoformat() + 'Z'
diff --git a/vk/tracking/online_sessions.py b/vk/tracking/online_sessions.py
index 204e1cc..11d3196 100644
--- a/vk/tracking/online_sessions.py
+++ b/vk/tracking/online_sessions.py
@@ -99,20 +99,20 @@ class OnlineSessionEnumerator(MutableMapping):
return by_hour
@staticmethod
- def _split_into_days(a, b):
- while a.date() != b.date():
- next_day = a.date() + timedelta(days=1)
- yield a.date(), next_day - a
- a = next_day
- yield b.date(), b - a
+ def _split_into_days(time_from, time_to):
+ while time_from.date() != time_to.date():
+ next_day = time_from.date() + timedelta(days=1)
+ yield time_from.date(), next_day - time_from
+ time_from = next_day
+ yield time_to.date(), time_to - time_from
@staticmethod
- def _split_into_hours(a, b):
- while a.date() != b.date() or a.hour != b.hour:
- next_hour = a.replace(minute=0, second=0) + timedelta(hours=1)
- yield a.hour, next_hour - a
- a = next_hour
- yield b.hour, b - a
+ def _split_into_hours(time_from, time_to):
+ while time_from.date() != time_to.date() or time_from.hour != time_to.hour:
+ next_hour = time_from.replace(minute=0, second=0) + timedelta(hours=1)
+ yield time_from.hour, next_hour - time_from
+ time_from = next_hour
+ yield time_to.hour, time_to - time_from
def _process_database_record(self, record):
return self._close_user_session(record.to_user())
diff --git a/vk/tracking/status_tracker.py b/vk/tracking/status_tracker.py
index d47de39..d52af6a 100644
--- a/vk/tracking/status_tracker.py
+++ b/vk/tracking/status_tracker.py
@@ -27,21 +27,21 @@ class StatusTracker:
self.add_status_update_handler(writer.on_status_update)
self.add_connection_error_handler(writer.on_connection_error)
- def add_initial_status_handler(self, fn):
- self._assert_is_callback(fn)
- self._on_initial_status.append(fn)
+ def add_initial_status_handler(self, handler):
+ self._assert_is_callback(handler)
+ self._on_initial_status.append(handler)
- def add_status_update_handler(self, fn):
- self._assert_is_callback(fn)
- self._on_status_update.append(fn)
+ def add_status_update_handler(self, handler):
+ self._assert_is_callback(handler)
+ self._on_status_update.append(handler)
- def add_connection_error_handler(self, fn):
- self._assert_is_callback(fn)
- self._on_connection_error.append(fn)
+ def add_connection_error_handler(self, handler):
+ self._assert_is_callback(handler)
+ self._on_connection_error.append(handler)
@staticmethod
- def _assert_is_callback(fn):
- if not isinstance(fn, Callable):
+ def _assert_is_callback(handler):
+ if not isinstance(handler, Callable):
raise TypeError()
_USER_FIELDS = UserField.DOMAIN, UserField.ONLINE, UserField.LAST_SEEN,
@@ -50,16 +50,16 @@ class StatusTracker:
return {user.get_uid(): user for user in self._api.users_get(uids, self._USER_FIELDS)}
def _notify_status(self, user):
- for fn in self._on_initial_status:
- fn(user)
+ for handler in self._on_initial_status:
+ handler(user)
def _notify_status_update(self, user):
- for fn in self._on_status_update:
- fn(user)
+ for handler in self._on_status_update:
+ handler(user)
def _notify_connection_error(self, e):
- for fn in self._on_connection_error:
- fn(e)
+ for handler in self._on_connection_error:
+ handler(e)
def _query_initial_status(self, uids):
while True:
diff --git a/vk/user.py b/vk/user.py
index f63f793..6fae83d 100644
--- a/vk/user.py
+++ b/vk/user.py
@@ -9,30 +9,30 @@ from enum import Enum
from .last_seen import LastSeen
-def _parse_last_seen(x):
- if isinstance(x, LastSeen):
- return x
- elif isinstance(x, Mapping):
- return LastSeen.from_api_response(x)
+def _parse_last_seen(src):
+ if isinstance(src, LastSeen):
+ return src
+ elif isinstance(src, Mapping):
+ return LastSeen.from_api_response(src)
else:
raise TypeError()
-def _parse_bool(x):
- if isinstance(x, str):
- if str(True) == x:
+def _parse_bool(src):
+ if isinstance(src, str):
+ if str(True) == src:
return True
- elif str(False) == x:
+ elif str(False) == src:
return False
else:
raise ValueError()
else:
- return bool(x)
+ return bool(src)
-def _parse_hidden(x):
- return _parse_bool(x)
+def _parse_hidden(src):
+ return _parse_bool(src)
-def _parse_online_flag(x):
- return _parse_bool(x)
+def _parse_online_flag(src):
+ return _parse_bool(src)
class UserField(Enum):
UID = 'uid'
@@ -56,8 +56,8 @@ class DeactivationReason(Enum):
def __str__(self):
return self.value
-def _parse_deactivated(s):
- return DeactivationReason(s)
+def _parse_deactivated(src):
+ return DeactivationReason(src)
class User(Hashable, MutableMapping):
@staticmethod