vk-scripts 1.0.4__tar.gz → 1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- vk_scripts-1.1/.git-blame-ignore-revs +1 -0
- {vk_scripts-1.0.4 → vk_scripts-1.1}/.github/workflows/ci.yml +21 -5
- vk_scripts-1.1/.pylintrc +8 -0
- {vk_scripts-1.0.4 → vk_scripts-1.1}/LICENSE.txt +1 -1
- {vk_scripts-1.0.4/vk_scripts.egg-info → vk_scripts-1.1}/PKG-INFO +4 -6
- {vk_scripts-1.0.4 → vk_scripts-1.1}/README.md +0 -2
- {vk_scripts-1.0.4 → vk_scripts-1.1}/docs/mutuals.md +6 -11
- {vk_scripts-1.0.4 → vk_scripts-1.1}/docs/sessions.md +0 -7
- {vk_scripts-1.0.4 → vk_scripts-1.1}/docs/status.md +0 -7
- {vk_scripts-1.0.4 → vk_scripts-1.1}/pyproject.toml +7 -4
- {vk_scripts-1.0.4 → vk_scripts-1.1}/test/bin/main.sh +1 -1
- {vk_scripts-1.0.4 → vk_scripts-1.1}/test/bin/mutuals.sh +1 -1
- {vk_scripts-1.0.4 → vk_scripts-1.1}/test/bin/sessions.sh +1 -1
- {vk_scripts-1.0.4 → vk_scripts-1.1}/test/bin/status.sh +1 -1
- {vk_scripts-1.0.4 → vk_scripts-1.1}/test/bin/status_once.sh +1 -1
- {vk_scripts-1.0.4 → vk_scripts-1.1}/test/lib/test.sh +1 -1
- {vk_scripts-1.0.4 → vk_scripts-1.1}/vk/api.py +40 -31
- {vk_scripts-1.0.4 → vk_scripts-1.1}/vk/error.py +1 -1
- {vk_scripts-1.0.4 → vk_scripts-1.1}/vk/last_seen.py +10 -16
- {vk_scripts-1.0.4 → vk_scripts-1.1}/vk/mutuals.py +34 -19
- vk_scripts-1.1/vk/platform.py +39 -0
- {vk_scripts-1.0.4 → vk_scripts-1.1}/vk/tracking/__init__.py +5 -2
- {vk_scripts-1.0.4 → vk_scripts-1.1}/vk/tracking/db/__init__.py +2 -2
- {vk_scripts-1.0.4 → vk_scripts-1.1}/vk/tracking/db/backend/__init__.py +6 -2
- {vk_scripts-1.0.4 → vk_scripts-1.1}/vk/tracking/db/backend/csv.py +3 -3
- {vk_scripts-1.0.4 → vk_scripts-1.1}/vk/tracking/db/backend/log.py +14 -21
- {vk_scripts-1.0.4 → vk_scripts-1.1}/vk/tracking/db/backend/null.py +1 -1
- {vk_scripts-1.0.4 → vk_scripts-1.1}/vk/tracking/db/format.py +12 -12
- {vk_scripts-1.0.4 → vk_scripts-1.1}/vk/tracking/db/meta.py +1 -1
- {vk_scripts-1.0.4 → vk_scripts-1.1}/vk/tracking/db/record.py +3 -3
- {vk_scripts-1.0.4 → vk_scripts-1.1}/vk/tracking/db/timestamp.py +3 -3
- {vk_scripts-1.0.4 → vk_scripts-1.1}/vk/tracking/sessions.py +109 -76
- {vk_scripts-1.0.4 → vk_scripts-1.1}/vk/tracking/status.py +61 -35
- {vk_scripts-1.0.4 → vk_scripts-1.1}/vk/user.py +40 -58
- {vk_scripts-1.0.4 → vk_scripts-1.1}/vk/utils/bar_chart.py +26 -23
- {vk_scripts-1.0.4 → vk_scripts-1.1}/vk/utils/io.py +8 -10
- vk_scripts-1.1/vk/version.py +16 -0
- {vk_scripts-1.0.4 → vk_scripts-1.1/vk_scripts.egg-info}/PKG-INFO +4 -6
- {vk_scripts-1.0.4 → vk_scripts-1.1}/vk_scripts.egg-info/SOURCES.txt +3 -0
- vk_scripts-1.1/vk_scripts.egg-info/scm_file_list.json +50 -0
- vk_scripts-1.1/vk_scripts.egg-info/scm_version.json +8 -0
- vk_scripts-1.0.4/.pylintrc +0 -7
- vk_scripts-1.0.4/vk/platform.py +0 -57
- vk_scripts-1.0.4/vk/version.py +0 -15
- {vk_scripts-1.0.4 → vk_scripts-1.1}/.gitattributes +0 -0
- {vk_scripts-1.0.4 → vk_scripts-1.1}/.github/dependabot.yml +0 -0
- {vk_scripts-1.0.4 → vk_scripts-1.1}/.gitignore +0 -0
- {vk_scripts-1.0.4 → vk_scripts-1.1}/docs/images/date.png +0 -0
- {vk_scripts-1.0.4 → vk_scripts-1.1}/docs/images/hour.png +0 -0
- {vk_scripts-1.0.4 → vk_scripts-1.1}/docs/images/user.png +0 -0
- {vk_scripts-1.0.4 → vk_scripts-1.1}/docs/images/weekday.png +0 -0
- {vk_scripts-1.0.4 → vk_scripts-1.1}/setup.cfg +0 -0
- {vk_scripts-1.0.4 → vk_scripts-1.1}/test/share/test_db.csv +0 -0
- {vk_scripts-1.0.4 → vk_scripts-1.1}/vk/__init__.py +0 -0
- {vk_scripts-1.0.4 → vk_scripts-1.1}/vk/utils/__init__.py +0 -0
- {vk_scripts-1.0.4 → vk_scripts-1.1}/vk_scripts.egg-info/dependency_links.txt +0 -0
- {vk_scripts-1.0.4 → vk_scripts-1.1}/vk_scripts.egg-info/entry_points.txt +0 -0
- {vk_scripts-1.0.4 → vk_scripts-1.1}/vk_scripts.egg-info/requires.txt +0 -0
- {vk_scripts-1.0.4 → vk_scripts-1.1}/vk_scripts.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
93ad1eb3a63041a49882e6b7b6b0ef506d4fa6c7
|
|
@@ -6,8 +6,8 @@ on:
|
|
|
6
6
|
- 'docs/**'
|
|
7
7
|
- 'README.md'
|
|
8
8
|
schedule:
|
|
9
|
-
# Weekly, at
|
|
10
|
-
- cron: '
|
|
9
|
+
# Weekly, at 02:30 on Friday (somewhat randomly chosen).
|
|
10
|
+
- cron: '30 02 * * 5'
|
|
11
11
|
workflow_dispatch:
|
|
12
12
|
|
|
13
13
|
env:
|
|
@@ -15,6 +15,22 @@ env:
|
|
|
15
15
|
PIP_NO_PYTHON_VERSION_WARNING: 1
|
|
16
16
|
|
|
17
17
|
jobs:
|
|
18
|
+
lint:
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
name: Linting
|
|
21
|
+
continue-on-error: "${{ github.ref != 'refs/heads/master' }}"
|
|
22
|
+
steps:
|
|
23
|
+
- name: Checkout
|
|
24
|
+
uses: actions/checkout@v7
|
|
25
|
+
with:
|
|
26
|
+
fetch-depth: 0
|
|
27
|
+
- name: Set up Python
|
|
28
|
+
uses: actions/setup-python@v6
|
|
29
|
+
with:
|
|
30
|
+
python-version: '3.x'
|
|
31
|
+
- name: Run black
|
|
32
|
+
uses: psf/black@stable
|
|
33
|
+
|
|
18
34
|
test:
|
|
19
35
|
strategy:
|
|
20
36
|
matrix:
|
|
@@ -25,7 +41,7 @@ jobs:
|
|
|
25
41
|
name: 'Python ${{ matrix.python-version }}'
|
|
26
42
|
steps:
|
|
27
43
|
- name: Checkout
|
|
28
|
-
uses: actions/checkout@
|
|
44
|
+
uses: actions/checkout@v7
|
|
29
45
|
with:
|
|
30
46
|
fetch-depth: 0
|
|
31
47
|
- name: Set up Python
|
|
@@ -43,12 +59,12 @@ jobs:
|
|
|
43
59
|
run: ./test/bin/main.sh
|
|
44
60
|
|
|
45
61
|
publish_pypi:
|
|
46
|
-
needs: [test]
|
|
62
|
+
needs: [lint, test]
|
|
47
63
|
runs-on: ubuntu-latest
|
|
48
64
|
name: Publish
|
|
49
65
|
steps:
|
|
50
66
|
- name: Checkout
|
|
51
|
-
uses: actions/checkout@
|
|
67
|
+
uses: actions/checkout@v7
|
|
52
68
|
with:
|
|
53
69
|
fetch-depth: 0
|
|
54
70
|
- name: Set up Python
|
vk_scripts-1.1/.pylintrc
ADDED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2015 Egor Tensin <
|
|
3
|
+
Copyright (c) 2015 Egor Tensin <egor@tensin.name>
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: vk_scripts
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.1
|
|
4
4
|
Summary: Scripts to stalk people on VK
|
|
5
|
-
Author-email: Egor Tensin <
|
|
5
|
+
Author-email: Egor Tensin <egor@tensin.name>
|
|
6
6
|
License-Expression: MIT
|
|
7
7
|
Project-URL: Homepage, https://github.com/egor-tensin/vk-scripts
|
|
8
8
|
Project-URL: Bug Tracker, https://github.com/egor-tensin/vk-scripts/issues
|
|
9
|
-
Classifier: Development Status ::
|
|
10
|
-
Requires-Python: >=3.
|
|
9
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
10
|
+
Requires-Python: >=3.6
|
|
11
11
|
Description-Content-Type: text/markdown
|
|
12
12
|
License-File: LICENSE.txt
|
|
13
13
|
Requires-Dist: importlib-metadata~=4.0; python_version < "3.8"
|
|
@@ -26,8 +26,6 @@ Installation
|
|
|
26
26
|
|
|
27
27
|
pip install vk-scripts
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
Python 3.4 or higher is required.
|
|
31
29
|
`vk-sessions` uses [matplotlib].
|
|
32
30
|
|
|
33
31
|
[matplotlib]: http://matplotlib.org/
|
|
@@ -13,8 +13,8 @@ Usage
|
|
|
13
13
|
For example (using made up user IDs/"screen names"),
|
|
14
14
|
|
|
15
15
|
> vk-mutuals john.doe jane.doe
|
|
16
|
-
89497105,John,Smith
|
|
17
|
-
3698577,Jane,Smith
|
|
16
|
+
89497105,John,Smith,john.smith
|
|
17
|
+
3698577,Jane,Smith,jane.smith
|
|
18
18
|
|
|
19
19
|
In the example above, both "John Doe" and "Jane Doe" are friends with "John
|
|
20
20
|
Smith" and "Jane Smith", whose user IDs are 89497105 and 3698577 respectively.
|
|
@@ -27,18 +27,13 @@ You can also get a JSON document:
|
|
|
27
27
|
{
|
|
28
28
|
"uid": 89497105,
|
|
29
29
|
"first_name": "John",
|
|
30
|
-
"last_name": "Smith"
|
|
30
|
+
"last_name": "Smith",
|
|
31
|
+
"domain": "john.smith"
|
|
31
32
|
},
|
|
32
33
|
{
|
|
33
34
|
"uid": 3698577,
|
|
34
35
|
"first_name": "Jane",
|
|
35
|
-
"last_name": "Smith"
|
|
36
|
+
"last_name": "Smith",
|
|
37
|
+
"domain": "jane.smith"
|
|
36
38
|
}
|
|
37
39
|
]
|
|
38
|
-
|
|
39
|
-
See also
|
|
40
|
-
--------
|
|
41
|
-
|
|
42
|
-
* [License]
|
|
43
|
-
|
|
44
|
-
[License]: ../README.md#license
|
|
@@ -159,10 +159,3 @@ Known issues
|
|
|
159
159
|
time (for example, just listening to music), they appear offline.
|
|
160
160
|
Hence the 0:00:00 durations you might sometimes encounter.
|
|
161
161
|
This might also happen using other clients.
|
|
162
|
-
|
|
163
|
-
See also
|
|
164
|
-
--------
|
|
165
|
-
|
|
166
|
-
* [License]
|
|
167
|
-
|
|
168
|
-
[License]: ../README.md#license
|
|
@@ -31,10 +31,3 @@ If you want to record when people go online/offline for further analysis using
|
|
|
31
31
|
[vk-sessions], specify the path to a database using the `--output` parameter.
|
|
32
32
|
|
|
33
33
|
[vk-sessions]: sessions.md
|
|
34
|
-
|
|
35
|
-
See also
|
|
36
|
-
--------
|
|
37
|
-
|
|
38
|
-
* [License]
|
|
39
|
-
|
|
40
|
-
[License]: ../README.md#license
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
[build-system]
|
|
2
|
-
|
|
2
|
+
# The SPDX license identifiers are available from 77.0.3:
|
|
3
|
+
# https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#license-and-license-files
|
|
4
|
+
requires = ["setuptools >= 77.0.3", "setuptools-scm"]
|
|
3
5
|
build-backend = "setuptools.build_meta"
|
|
4
6
|
|
|
5
7
|
[project]
|
|
6
8
|
name = "vk_scripts"
|
|
7
9
|
description = "Scripts to stalk people on VK"
|
|
8
10
|
license = "MIT"
|
|
11
|
+
license-files = ["LICENSE.txt"]
|
|
9
12
|
dynamic = ["version"]
|
|
10
|
-
authors = [{name = "Egor Tensin", email = "
|
|
13
|
+
authors = [{name = "Egor Tensin", email = "egor@tensin.name"}]
|
|
11
14
|
readme = "README.md"
|
|
12
|
-
requires-python = ">=3.
|
|
15
|
+
requires-python = ">=3.6"
|
|
13
16
|
|
|
14
17
|
dependencies = [
|
|
15
18
|
'importlib-metadata ~= 4.0 ; python_version < "3.8"',
|
|
@@ -17,7 +20,7 @@ dependencies = [
|
|
|
17
20
|
]
|
|
18
21
|
|
|
19
22
|
classifiers = [
|
|
20
|
-
"Development Status ::
|
|
23
|
+
"Development Status :: 5 - Production/Stable",
|
|
21
24
|
]
|
|
22
25
|
|
|
23
26
|
[project.urls]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
|
|
3
|
-
# Copyright (c) 2019 Egor Tensin <
|
|
3
|
+
# Copyright (c) 2019 Egor Tensin <egor@tensin.name>
|
|
4
4
|
# This file is part of the "VK scripts" project.
|
|
5
5
|
# For details, see https://github.com/egor-tensin/vk-scripts.
|
|
6
6
|
# Distributed under the MIT License.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
|
|
3
|
-
# Copyright (c) 2019 Egor Tensin <
|
|
3
|
+
# Copyright (c) 2019 Egor Tensin <egor@tensin.name>
|
|
4
4
|
# This file is part of the "VK scripts" project.
|
|
5
5
|
# For details, see https://github.com/egor-tensin/vk-scripts.
|
|
6
6
|
# Distributed under the MIT License.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
|
|
3
|
-
# Copyright (c) 2019 Egor Tensin <
|
|
3
|
+
# Copyright (c) 2019 Egor Tensin <egor@tensin.name>
|
|
4
4
|
# This file is part of the "VK scripts" project.
|
|
5
5
|
# For details, see https://github.com/egor-tensin/vk-scripts.
|
|
6
6
|
# Distributed under the MIT License.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
|
|
3
|
-
# Copyright (c) 2019 Egor Tensin <
|
|
3
|
+
# Copyright (c) 2019 Egor Tensin <egor@tensin.name>
|
|
4
4
|
# This file is part of the "VK scripts" project.
|
|
5
5
|
# For details, see https://github.com/egor-tensin/vk-scripts.
|
|
6
6
|
# Distributed under the MIT License.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
|
|
3
|
-
# Copyright (c) 2019 Egor Tensin <
|
|
3
|
+
# Copyright (c) 2019 Egor Tensin <egor@tensin.name>
|
|
4
4
|
# This file is part of the "VK scripts" project.
|
|
5
5
|
# For details, see https://github.com/egor-tensin/vk-scripts.
|
|
6
6
|
# Distributed under the MIT License.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
|
|
3
|
-
# Copyright (c) 2020 Egor Tensin <
|
|
3
|
+
# Copyright (c) 2020 Egor Tensin <egor@tensin.name>
|
|
4
4
|
# This file is part of the "VK scripts" project.
|
|
5
5
|
# For details, see https://github.com/egor-tensin/vk-scripts.
|
|
6
6
|
# Distributed under the MIT License.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (c) 2015 Egor Tensin <
|
|
1
|
+
# Copyright (c) 2015 Egor Tensin <egor@tensin.name>
|
|
2
2
|
# This file is part of the "VK scripts" project.
|
|
3
3
|
# For details, see https://github.com/egor-tensin/vk-scripts.
|
|
4
4
|
# Distributed under the MIT License.
|
|
@@ -26,9 +26,15 @@ def _filter_empty_params(params, empty_params=False):
|
|
|
26
26
|
if empty_params:
|
|
27
27
|
return params
|
|
28
28
|
if isinstance(params, Mapping):
|
|
29
|
-
return {
|
|
29
|
+
return {
|
|
30
|
+
name: value
|
|
31
|
+
for name, value in params.items()
|
|
32
|
+
if not _is_empty_param_value(value)
|
|
33
|
+
}
|
|
30
34
|
if isinstance(params, Iterable):
|
|
31
|
-
return [
|
|
35
|
+
return [
|
|
36
|
+
(name, value) for name, value in params if not _is_empty_param_value(value)
|
|
37
|
+
]
|
|
32
38
|
raise TypeError()
|
|
33
39
|
|
|
34
40
|
|
|
@@ -43,28 +49,29 @@ def _build_url(scheme, host, path, params=None, empty_params=False):
|
|
|
43
49
|
else:
|
|
44
50
|
raise TypeError()
|
|
45
51
|
path = urllib.parse.quote(path)
|
|
46
|
-
return urllib.parse.urlunsplit((scheme, host, path, params,
|
|
52
|
+
return urllib.parse.urlunsplit((scheme, host, path, params, ""))
|
|
47
53
|
|
|
48
54
|
|
|
49
55
|
def _join_param_values(values):
|
|
50
56
|
if isinstance(values, str):
|
|
51
57
|
return values
|
|
52
58
|
if isinstance(values, Iterable):
|
|
53
|
-
return
|
|
59
|
+
return ",".join(map(str, values))
|
|
54
60
|
return values
|
|
55
61
|
|
|
56
62
|
|
|
57
63
|
def _join_path(base, url):
|
|
58
|
-
if not base.endswith(
|
|
59
|
-
base +=
|
|
64
|
+
if not base.endswith("/"):
|
|
65
|
+
base += "/"
|
|
60
66
|
return urllib.parse.urljoin(base, url)
|
|
61
67
|
|
|
62
68
|
|
|
63
|
-
ACCESS_TOKEN =
|
|
69
|
+
ACCESS_TOKEN = "9722cef09722cef09722cef071974b8cbe997229722cef0cbabfd816916af6c7bd37006"
|
|
64
70
|
|
|
65
71
|
|
|
66
72
|
class Version(Enum):
|
|
67
|
-
|
|
73
|
+
# https://dev.vk.com/en/reference/versions
|
|
74
|
+
V5_199 = "5.199"
|
|
68
75
|
DEFAULT = V5_199
|
|
69
76
|
|
|
70
77
|
def __str__(self):
|
|
@@ -72,7 +79,7 @@ class Version(Enum):
|
|
|
72
79
|
|
|
73
80
|
|
|
74
81
|
class Language(Enum):
|
|
75
|
-
EN =
|
|
82
|
+
EN = "en"
|
|
76
83
|
DEFAULT = EN
|
|
77
84
|
|
|
78
85
|
def __str__(self):
|
|
@@ -80,24 +87,24 @@ class Language(Enum):
|
|
|
80
87
|
|
|
81
88
|
|
|
82
89
|
class Method(Enum):
|
|
83
|
-
USERS_GET =
|
|
84
|
-
FRIENDS_GET =
|
|
90
|
+
USERS_GET = "users.get"
|
|
91
|
+
FRIENDS_GET = "friends.get"
|
|
85
92
|
|
|
86
93
|
def __str__(self):
|
|
87
94
|
return self.value
|
|
88
95
|
|
|
89
96
|
|
|
90
97
|
class CommonParameters(Enum):
|
|
91
|
-
ACCESS_TOKEN =
|
|
92
|
-
VERSION =
|
|
93
|
-
LANGUAGE =
|
|
98
|
+
ACCESS_TOKEN = "access_token"
|
|
99
|
+
VERSION = "v"
|
|
100
|
+
LANGUAGE = "lang"
|
|
94
101
|
|
|
95
102
|
def __str__(self):
|
|
96
103
|
return self.value
|
|
97
104
|
|
|
98
105
|
|
|
99
106
|
class API:
|
|
100
|
-
_ROOT_URL =
|
|
107
|
+
_ROOT_URL = "https://api.vk.com/method/"
|
|
101
108
|
|
|
102
109
|
_SCHEME, _HOST, _ROOT_PATH = _split_url(_ROOT_URL)
|
|
103
110
|
|
|
@@ -115,14 +122,14 @@ class API:
|
|
|
115
122
|
|
|
116
123
|
def _call_method(self, method, **params):
|
|
117
124
|
url = self._build_method_url(method, **params)
|
|
118
|
-
#print(url)
|
|
125
|
+
# print(url)
|
|
119
126
|
try:
|
|
120
127
|
with urlopen(url) as response:
|
|
121
128
|
response = json.loads(response.read().decode())
|
|
122
|
-
#print(response)
|
|
123
|
-
if
|
|
129
|
+
# print(response)
|
|
130
|
+
if "response" not in response:
|
|
124
131
|
raise vk.error.InvalidAPIResponseError(response)
|
|
125
|
-
return response[
|
|
132
|
+
return response["response"]
|
|
126
133
|
except (ConnectionError, URLError) as e:
|
|
127
134
|
raise vk.error.APIConnectionError(str(e)) from e
|
|
128
135
|
|
|
@@ -131,20 +138,22 @@ class API:
|
|
|
131
138
|
user_list = map(User.from_api_response, user_list)
|
|
132
139
|
if deactivated_users:
|
|
133
140
|
return user_list
|
|
134
|
-
return [user for user in user_list if not user.is_deactivated
|
|
141
|
+
return [user for user in user_list if not user.is_deactivated]
|
|
135
142
|
|
|
136
143
|
def users_get(self, user_ids, fields=(), deactivated_users=True):
|
|
137
|
-
return self._filter_response_with_users(
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
144
|
+
return self._filter_response_with_users(
|
|
145
|
+
self._call_method(
|
|
146
|
+
Method.USERS_GET,
|
|
147
|
+
user_ids=_join_param_values(user_ids),
|
|
148
|
+
fields=_join_param_values(fields),
|
|
149
|
+
),
|
|
150
|
+
deactivated_users,
|
|
151
|
+
)
|
|
141
152
|
|
|
142
153
|
def friends_get(self, user_id, fields=(), deactivated_users=True):
|
|
143
154
|
response = self._call_method(
|
|
144
|
-
Method.FRIENDS_GET,
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
if 'items' not in response:
|
|
155
|
+
Method.FRIENDS_GET, user_id=user_id, fields=_join_param_values(fields)
|
|
156
|
+
)
|
|
157
|
+
if "items" not in response:
|
|
148
158
|
raise vk.error.InvalidAPIResponseError(response)
|
|
149
|
-
return self._filter_response_with_users(response[
|
|
150
|
-
deactivated_users)
|
|
159
|
+
return self._filter_response_with_users(response["items"], deactivated_users)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (c) 2016 Egor Tensin <
|
|
1
|
+
# Copyright (c) 2016 Egor Tensin <egor@tensin.name>
|
|
2
2
|
# This file is part of the "VK scripts" project.
|
|
3
3
|
# For details, see https://github.com/egor-tensin/vk-scripts.
|
|
4
4
|
# Distributed under the MIT License.
|
|
@@ -31,8 +31,8 @@ def _parse_platform(x):
|
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
class LastSeenField(Enum):
|
|
34
|
-
TIME =
|
|
35
|
-
PLATFORM =
|
|
34
|
+
TIME = "time"
|
|
35
|
+
PLATFORM = "platform"
|
|
36
36
|
|
|
37
37
|
def __str__(self):
|
|
38
38
|
return self.value
|
|
@@ -80,20 +80,14 @@ class LastSeen(MutableMapping):
|
|
|
80
80
|
|
|
81
81
|
_DEFAULT_FIELD_PARSER = str
|
|
82
82
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
def get_time(self):
|
|
83
|
+
@property
|
|
84
|
+
def time(self):
|
|
87
85
|
return self[LastSeenField.TIME]
|
|
88
86
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
def has_platform(self):
|
|
93
|
-
return LastSeenField.PLATFORM in self
|
|
87
|
+
@property
|
|
88
|
+
def time_local(self):
|
|
89
|
+
return self.time.astimezone()
|
|
94
90
|
|
|
95
|
-
|
|
91
|
+
@property
|
|
92
|
+
def platform(self):
|
|
96
93
|
return self[LastSeenField.PLATFORM]
|
|
97
|
-
|
|
98
|
-
def set_platform(self, platform):
|
|
99
|
-
self[LastSeenField.PLATFORM] = platform
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (c) 2015 Egor Tensin <
|
|
1
|
+
# Copyright (c) 2015 Egor Tensin <egor@tensin.name>
|
|
2
2
|
# This file is part of the "VK scripts" project.
|
|
3
3
|
# For details, see https://github.com/egor-tensin/vk-scripts.
|
|
4
4
|
# Distributed under the MIT License.
|
|
@@ -14,12 +14,16 @@ from vk.user import UserField
|
|
|
14
14
|
from vk.utils import io
|
|
15
15
|
import vk.version
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
_OUTPUT_USER_FIELDS = (
|
|
18
|
+
UserField.UID,
|
|
19
|
+
UserField.FIRST_NAME,
|
|
20
|
+
UserField.LAST_NAME,
|
|
21
|
+
UserField.DOMAIN,
|
|
22
|
+
)
|
|
19
23
|
|
|
20
24
|
|
|
21
25
|
def _query_friend_list(api, user):
|
|
22
|
-
return api.friends_get(user.
|
|
26
|
+
return api.friends_get(user.uid, fields=_OUTPUT_USER_FIELDS)
|
|
23
27
|
|
|
24
28
|
|
|
25
29
|
def _filter_user_fields(user):
|
|
@@ -53,8 +57,8 @@ class OutputSinkJSON(OutputSinkMutualFriends):
|
|
|
53
57
|
|
|
54
58
|
|
|
55
59
|
class OutputFormat(Enum):
|
|
56
|
-
CSV =
|
|
57
|
-
JSON =
|
|
60
|
+
CSV = "csv"
|
|
61
|
+
JSON = "json"
|
|
58
62
|
|
|
59
63
|
def __str__(self):
|
|
60
64
|
return self.value
|
|
@@ -68,14 +72,14 @@ class OutputFormat(Enum):
|
|
|
68
72
|
return OutputSinkCSV(fd)
|
|
69
73
|
if self is OutputFormat.JSON:
|
|
70
74
|
return OutputSinkJSON(fd)
|
|
71
|
-
raise NotImplementedError(
|
|
75
|
+
raise NotImplementedError(f"unsupported output format: {self}")
|
|
72
76
|
|
|
73
77
|
|
|
74
78
|
def _parse_output_format(s):
|
|
75
79
|
try:
|
|
76
80
|
return OutputFormat(s)
|
|
77
81
|
except ValueError:
|
|
78
|
-
raise argparse.ArgumentTypeError(
|
|
82
|
+
raise argparse.ArgumentTypeError(f"invalid output format: {s}")
|
|
79
83
|
|
|
80
84
|
|
|
81
85
|
def _parse_args(args=None):
|
|
@@ -83,19 +87,30 @@ def _parse_args(args=None):
|
|
|
83
87
|
args = sys.argv[1:]
|
|
84
88
|
|
|
85
89
|
parser = argparse.ArgumentParser(
|
|
86
|
-
description=
|
|
90
|
+
description="Learn who your ex and her new boyfriend are both friends with."
|
|
91
|
+
)
|
|
87
92
|
|
|
88
93
|
vk.version.add_to_arg_parser(parser)
|
|
89
94
|
|
|
90
|
-
parser.add_argument(
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
95
|
+
parser.add_argument(
|
|
96
|
+
"uids", metavar="UID", nargs="+", help='user IDs or "screen names"'
|
|
97
|
+
)
|
|
98
|
+
parser.add_argument(
|
|
99
|
+
"-f",
|
|
100
|
+
"--format",
|
|
101
|
+
dest="out_fmt",
|
|
102
|
+
type=_parse_output_format,
|
|
103
|
+
default=OutputFormat.CSV,
|
|
104
|
+
choices=OutputFormat,
|
|
105
|
+
help="specify output format",
|
|
106
|
+
)
|
|
107
|
+
parser.add_argument(
|
|
108
|
+
"-o",
|
|
109
|
+
"--output",
|
|
110
|
+
metavar="PATH",
|
|
111
|
+
dest="out_path",
|
|
112
|
+
help="set output file path (standard output by default)",
|
|
113
|
+
)
|
|
99
114
|
|
|
100
115
|
return parser.parse_args(args)
|
|
101
116
|
|
|
@@ -117,5 +132,5 @@ def main(args=None):
|
|
|
117
132
|
write_mutual_friends(**vars(_parse_args(args)))
|
|
118
133
|
|
|
119
134
|
|
|
120
|
-
if __name__ ==
|
|
135
|
+
if __name__ == "__main__":
|
|
121
136
|
main()
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Copyright (c) 2016 Egor Tensin <egor@tensin.name>
|
|
2
|
+
# This file is part of the "VK scripts" project.
|
|
3
|
+
# For details, see https://github.com/egor-tensin/vk-scripts.
|
|
4
|
+
# Distributed under the MIT License.
|
|
5
|
+
|
|
6
|
+
from enum import Enum
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Platform(Enum):
|
|
10
|
+
# https://dev.vk.com/en/reference/objects/user#last_seen
|
|
11
|
+
MOBILE = 1
|
|
12
|
+
IPHONE = 2
|
|
13
|
+
IPAD = 3
|
|
14
|
+
ANDROID = 4
|
|
15
|
+
WINDOWS_PHONE = 5
|
|
16
|
+
WINDOWS10 = 6
|
|
17
|
+
WEB = 7
|
|
18
|
+
|
|
19
|
+
@staticmethod
|
|
20
|
+
def from_string(s):
|
|
21
|
+
return Platform(int(s))
|
|
22
|
+
|
|
23
|
+
def __str__(self):
|
|
24
|
+
return str(self.value)
|
|
25
|
+
|
|
26
|
+
@property
|
|
27
|
+
def descr(self):
|
|
28
|
+
return f"the {_PLATFORM_DESCRIPTIONS[self]}"
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
_PLATFORM_DESCRIPTIONS = {
|
|
32
|
+
Platform.MOBILE: '"mobile" web version (or an unrecognized mobile app)',
|
|
33
|
+
Platform.IPHONE: "official iPhone app",
|
|
34
|
+
Platform.IPAD: "official iPad app",
|
|
35
|
+
Platform.ANDROID: "official Android app",
|
|
36
|
+
Platform.WINDOWS_PHONE: "official Windows Phone app",
|
|
37
|
+
Platform.WINDOWS10: "official Windows 10 app",
|
|
38
|
+
Platform.WEB: "web version (or an unrecognized app)",
|
|
39
|
+
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
# Copyright 2016 Egor Tensin <
|
|
1
|
+
# Copyright 2016 Egor Tensin <egor@tensin.name>
|
|
2
2
|
# This file is licensed under the terms of the MIT License.
|
|
3
3
|
# See LICENSE.txt for details.
|
|
4
4
|
|
|
5
|
-
__all__ =
|
|
5
|
+
__all__ = (
|
|
6
|
+
"sessions",
|
|
7
|
+
"status",
|
|
8
|
+
)
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
# Copyright (c) 2016 Egor Tensin <
|
|
1
|
+
# Copyright (c) 2016 Egor Tensin <egor@tensin.name>
|
|
2
2
|
# This file is part of the "VK scripts" project.
|
|
3
3
|
# For details, see https://github.com/egor-tensin/vk-scripts.
|
|
4
4
|
# Distributed under the MIT License.
|
|
5
5
|
|
|
6
6
|
from .format import Format
|
|
7
7
|
|
|
8
|
-
__all__ =
|
|
8
|
+
__all__ = ("format",)
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
# Copyright (c) 2016 Egor Tensin <
|
|
1
|
+
# Copyright (c) 2016 Egor Tensin <egor@tensin.name>
|
|
2
2
|
# This file is part of the "VK scripts" project.
|
|
3
3
|
# For details, see https://github.com/egor-tensin/vk-scripts.
|
|
4
4
|
# Distributed under the MIT License.
|
|
5
5
|
|
|
6
6
|
from . import csv, log, null
|
|
7
7
|
|
|
8
|
-
__all__ =
|
|
8
|
+
__all__ = (
|
|
9
|
+
"csv",
|
|
10
|
+
"log",
|
|
11
|
+
"null",
|
|
12
|
+
)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (c) 2016 Egor Tensin <
|
|
1
|
+
# Copyright (c) 2016 Egor Tensin <egor@tensin.name>
|
|
2
2
|
# This file is part of the "VK scripts" project.
|
|
3
3
|
# For details, see https://github.com/egor-tensin/vk-scripts.
|
|
4
4
|
# Distributed under the MIT License.
|
|
@@ -43,6 +43,6 @@ class Reader(meta.Reader):
|
|
|
43
43
|
@staticmethod
|
|
44
44
|
def _record_from_row(row):
|
|
45
45
|
record = Record(Timestamp.from_string(row[0]))
|
|
46
|
-
for i in
|
|
47
|
-
record[
|
|
46
|
+
for i, field in enumerate(Record.FIELDS):
|
|
47
|
+
record[field] = row[i + 1]
|
|
48
48
|
return record
|