vk-scripts 1.0.2__tar.gz → 1.0.4__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.
Files changed (57) hide show
  1. vk_scripts-1.0.4/.gitattributes +3 -0
  2. vk_scripts-1.0.4/.github/dependabot.yml +6 -0
  3. vk_scripts-1.0.4/.github/workflows/ci.yml +75 -0
  4. vk_scripts-1.0.4/.gitignore +6 -0
  5. vk_scripts-1.0.4/.pylintrc +7 -0
  6. {vk_scripts-1.0.2 → vk_scripts-1.0.4}/PKG-INFO +16 -10
  7. {vk_scripts-1.0.2 → vk_scripts-1.0.4}/README.md +8 -0
  8. vk_scripts-1.0.4/docs/images/date.png +0 -0
  9. vk_scripts-1.0.4/docs/images/hour.png +0 -0
  10. vk_scripts-1.0.4/docs/images/user.png +0 -0
  11. vk_scripts-1.0.4/docs/images/weekday.png +0 -0
  12. vk_scripts-1.0.4/docs/mutuals.md +44 -0
  13. vk_scripts-1.0.4/docs/sessions.md +168 -0
  14. vk_scripts-1.0.4/docs/status.md +40 -0
  15. vk_scripts-1.0.4/pyproject.toml +32 -0
  16. vk_scripts-1.0.4/setup.cfg +4 -0
  17. vk_scripts-1.0.4/test/bin/main.sh +19 -0
  18. vk_scripts-1.0.4/test/bin/mutuals.sh +23 -0
  19. vk_scripts-1.0.4/test/bin/sessions.sh +69 -0
  20. vk_scripts-1.0.4/test/bin/status.sh +60 -0
  21. vk_scripts-1.0.4/test/bin/status_once.sh +22 -0
  22. vk_scripts-1.0.4/test/lib/test.sh +27 -0
  23. vk_scripts-1.0.4/test/share/test_db.csv +45 -0
  24. {vk_scripts-1.0.2 → vk_scripts-1.0.4}/vk/api.py +2 -2
  25. {vk_scripts-1.0.2 → vk_scripts-1.0.4}/vk/mutuals.py +3 -0
  26. {vk_scripts-1.0.2 → vk_scripts-1.0.4}/vk/tracking/db/backend/log.py +1 -1
  27. {vk_scripts-1.0.2 → vk_scripts-1.0.4}/vk/tracking/sessions.py +3 -0
  28. {vk_scripts-1.0.2 → vk_scripts-1.0.4}/vk/tracking/status.py +4 -1
  29. vk_scripts-1.0.4/vk/version.py +15 -0
  30. {vk_scripts-1.0.2 → vk_scripts-1.0.4}/vk_scripts.egg-info/PKG-INFO +17 -11
  31. {vk_scripts-1.0.2 → vk_scripts-1.0.4}/vk_scripts.egg-info/SOURCES.txt +20 -2
  32. {vk_scripts-1.0.2 → vk_scripts-1.0.4}/vk_scripts.egg-info/entry_points.txt +0 -1
  33. vk_scripts-1.0.4/vk_scripts.egg-info/requires.txt +4 -0
  34. vk_scripts-1.0.2/pyproject.toml +0 -3
  35. vk_scripts-1.0.2/setup.cfg +0 -32
  36. vk_scripts-1.0.2/setup.py +0 -2
  37. vk_scripts-1.0.2/vk_scripts.egg-info/requires.txt +0 -1
  38. {vk_scripts-1.0.2 → vk_scripts-1.0.4}/LICENSE.txt +0 -0
  39. {vk_scripts-1.0.2 → vk_scripts-1.0.4}/vk/__init__.py +0 -0
  40. {vk_scripts-1.0.2 → vk_scripts-1.0.4}/vk/error.py +0 -0
  41. {vk_scripts-1.0.2 → vk_scripts-1.0.4}/vk/last_seen.py +0 -0
  42. {vk_scripts-1.0.2 → vk_scripts-1.0.4}/vk/platform.py +0 -0
  43. {vk_scripts-1.0.2 → vk_scripts-1.0.4}/vk/tracking/__init__.py +0 -0
  44. {vk_scripts-1.0.2 → vk_scripts-1.0.4}/vk/tracking/db/__init__.py +0 -0
  45. {vk_scripts-1.0.2 → vk_scripts-1.0.4}/vk/tracking/db/backend/__init__.py +0 -0
  46. {vk_scripts-1.0.2 → vk_scripts-1.0.4}/vk/tracking/db/backend/csv.py +0 -0
  47. {vk_scripts-1.0.2 → vk_scripts-1.0.4}/vk/tracking/db/backend/null.py +0 -0
  48. {vk_scripts-1.0.2 → vk_scripts-1.0.4}/vk/tracking/db/format.py +0 -0
  49. {vk_scripts-1.0.2 → vk_scripts-1.0.4}/vk/tracking/db/meta.py +0 -0
  50. {vk_scripts-1.0.2 → vk_scripts-1.0.4}/vk/tracking/db/record.py +0 -0
  51. {vk_scripts-1.0.2 → vk_scripts-1.0.4}/vk/tracking/db/timestamp.py +0 -0
  52. {vk_scripts-1.0.2 → vk_scripts-1.0.4}/vk/user.py +0 -0
  53. {vk_scripts-1.0.2 → vk_scripts-1.0.4}/vk/utils/__init__.py +0 -0
  54. {vk_scripts-1.0.2 → vk_scripts-1.0.4}/vk/utils/bar_chart.py +0 -0
  55. {vk_scripts-1.0.2 → vk_scripts-1.0.4}/vk/utils/io.py +0 -0
  56. {vk_scripts-1.0.2 → vk_scripts-1.0.4}/vk_scripts.egg-info/dependency_links.txt +0 -0
  57. {vk_scripts-1.0.2 → vk_scripts-1.0.4}/vk_scripts.egg-info/top_level.txt +0 -0
@@ -0,0 +1,3 @@
1
+ * text=auto
2
+
3
+ *.sh text eol=lf
@@ -0,0 +1,6 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: github-actions
4
+ directory: /
5
+ schedule:
6
+ interval: weekly
@@ -0,0 +1,75 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ paths-ignore:
6
+ - 'docs/**'
7
+ - 'README.md'
8
+ schedule:
9
+ # Weekly, at 6:45 AM on Thursday (somewhat randomly chosen).
10
+ - cron: '45 6 * * 4'
11
+ workflow_dispatch:
12
+
13
+ env:
14
+ PIP_DISABLE_PIP_VERSION_CHECK: 1
15
+ PIP_NO_PYTHON_VERSION_WARNING: 1
16
+
17
+ jobs:
18
+ test:
19
+ strategy:
20
+ matrix:
21
+ python-version: ['3.9', '3.10', '3.11', '3.12', '3.13', '3.14']
22
+ # Random number to prevent exceeding the request frequency limit.
23
+ max-parallel: 3
24
+ runs-on: ubuntu-latest
25
+ name: 'Python ${{ matrix.python-version }}'
26
+ steps:
27
+ - name: Checkout
28
+ uses: actions/checkout@v6
29
+ with:
30
+ fetch-depth: 0
31
+ - name: Set up Python
32
+ uses: actions/setup-python@v6
33
+ with:
34
+ python-version: '${{ matrix.python-version }}'
35
+ - name: 'Install package & dependencies'
36
+ run: pip install -q -e .
37
+ - name: Check that scripts are runnable
38
+ run: |
39
+ vk-mutuals --version
40
+ vk-status --version
41
+ vk-sessions --version
42
+ - name: Run tests
43
+ run: ./test/bin/main.sh
44
+
45
+ publish_pypi:
46
+ needs: [test]
47
+ runs-on: ubuntu-latest
48
+ name: Publish
49
+ steps:
50
+ - name: Checkout
51
+ uses: actions/checkout@v6
52
+ with:
53
+ fetch-depth: 0
54
+ - name: Set up Python
55
+ uses: actions/setup-python@v6
56
+ with:
57
+ python-version: '3.x'
58
+ - name: Verify package can be installed
59
+ run: pip install -q .
60
+ - name: Install package builder
61
+ run: pip install -q --upgrade build
62
+ - name: Build package
63
+ run: python -m build
64
+ - name: Publish as artifact
65
+ uses: actions/upload-artifact@v7
66
+ with:
67
+ name: dist
68
+ path: dist
69
+ if-no-files-found: error
70
+ - name: Publish to PyPI
71
+ if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
72
+ uses: pypa/gh-action-pypi-publish@release/v1
73
+ with:
74
+ user: __token__
75
+ password: '${{ secrets.PYPI_API_TOKEN }}'
@@ -0,0 +1,6 @@
1
+ __pycache__/
2
+
3
+ /*.csv
4
+ /*.json
5
+ /*.log
6
+ /*.png
@@ -0,0 +1,7 @@
1
+ [MESSAGES CONTROL]
2
+
3
+ disable=invalid-name,missing-docstring,multiple-imports,too-many-public-methods,too-few-public-methods
4
+
5
+ [BASIC]
6
+
7
+ bad-functions=
@@ -1,18 +1,18 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: vk_scripts
3
- Version: 1.0.2
3
+ Version: 1.0.4
4
4
  Summary: Scripts to stalk people on VK
5
- Home-page: https://github.com/egor-tensin/vk-scripts
6
- Author: Egor Tensin
7
- Author-email: Egor.Tensin@gmail.com
8
- License: MIT
5
+ Author-email: Egor Tensin <Egor.Tensin@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/egor-tensin/vk-scripts
9
8
  Project-URL: Bug Tracker, https://github.com/egor-tensin/vk-scripts/issues
10
- Platform: UNKNOWN
11
9
  Classifier: Development Status :: 4 - Beta
12
- Classifier: License :: OSI Approved :: MIT License
13
10
  Requires-Python: >=3.4
14
11
  Description-Content-Type: text/markdown
15
12
  License-File: LICENSE.txt
13
+ Requires-Dist: importlib-metadata~=4.0; python_version < "3.8"
14
+ Requires-Dist: matplotlib
15
+ Dynamic: license-file
16
16
 
17
17
  VK scripts
18
18
  ==========
@@ -55,6 +55,14 @@ Requires [Pylint].
55
55
 
56
56
  [Pylint]: https://www.pylint.org/
57
57
 
58
+ ### Releases
59
+
60
+ Make a git tag:
61
+
62
+ git tag "v$( python -m setuptools_scm --strip-dev )"
63
+
64
+ You can then review that the tag is fine and push w/ `git push --tags`.
65
+
58
66
  License
59
67
  -------
60
68
 
@@ -62,5 +70,3 @@ Distributed under the MIT License.
62
70
  See [LICENSE.txt] for details.
63
71
 
64
72
  [LICENSE.txt]: LICENSE.txt
65
-
66
-
@@ -39,6 +39,14 @@ Requires [Pylint].
39
39
 
40
40
  [Pylint]: https://www.pylint.org/
41
41
 
42
+ ### Releases
43
+
44
+ Make a git tag:
45
+
46
+ git tag "v$( python -m setuptools_scm --strip-dev )"
47
+
48
+ You can then review that the tag is fine and push w/ `git push --tags`.
49
+
42
50
  License
43
51
  -------
44
52
 
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,44 @@
1
+ vk-mutuals
2
+ ==========
3
+
4
+ Learn who your ex and her new boyfriend are both friends with.
5
+
6
+ Usage
7
+ -----
8
+
9
+ > vk-mutuals -h
10
+ usage: vk-mutuals [-h] [-f {csv,json}] [-o PATH] UID [UID ...]
11
+ ...
12
+
13
+ For example (using made up user IDs/"screen names"),
14
+
15
+ > vk-mutuals john.doe jane.doe
16
+ 89497105,John,Smith
17
+ 3698577,Jane,Smith
18
+
19
+ In the example above, both "John Doe" and "Jane Doe" are friends with "John
20
+ Smith" and "Jane Smith", whose user IDs are 89497105 and 3698577 respectively.
21
+
22
+ The output format is CSV (comma-separated values) by default.
23
+ You can also get a JSON document:
24
+
25
+ > vk-mutuals --format json john.doe jane.doe
26
+ [
27
+ {
28
+ "uid": 89497105,
29
+ "first_name": "John",
30
+ "last_name": "Smith"
31
+ },
32
+ {
33
+ "uid": 3698577,
34
+ "first_name": "Jane",
35
+ "last_name": "Smith"
36
+ }
37
+ ]
38
+
39
+ See also
40
+ --------
41
+
42
+ * [License]
43
+
44
+ [License]: ../README.md#license
@@ -0,0 +1,168 @@
1
+ vk-sessions
2
+ ===========
3
+
4
+ View/visualize the amount of time people spend online.
5
+
6
+ Usage
7
+ -----
8
+
9
+ ```
10
+ > vk-sessions -h
11
+ usage: vk-sessions [-h] [-g {user,date,weekday,hour}] [-i {csv,log,null}]
12
+ [-o {csv,json,plot}] [-a TIME_FROM] [-b TIME_TO]
13
+ [input] [output]
14
+ ```
15
+
16
+ This script additionally requires [matplotlib] to be installed.
17
+
18
+ Analyze the database produced by [vk-status] and calculate the total amount of
19
+ time people spent online.
20
+ For example (assuming the database in "db.csv" was generated by [vk-status]
21
+ before):
22
+
23
+ ```
24
+ > vk-sessions db.csv
25
+ 89497105,John,Smith,john.smith,0:12:31
26
+ 3698577,Jane,Smith,jane.smith,1:34:46
27
+ ```
28
+
29
+ In the example above, "John Smith" and "Jane Smith" spent approx. 13 and 95
30
+ minutes online respectively.
31
+
32
+ The output format is CSV (comma-separated values) by default.
33
+ You can also get a JSON document:
34
+
35
+ ```
36
+ > vk-sessions --output-format json db.csv
37
+ [
38
+ {
39
+ "uid": 89497105,
40
+ "first_name": "John",
41
+ "last_name": "Smith",
42
+ "domain": "john.smith",
43
+ "duration": "0:12:31"
44
+ },
45
+ {
46
+ "uid": 3698577,
47
+ "first_name": "Jane",
48
+ "last_name": "Smith",
49
+ "domain": "jane.smith",
50
+ "duration": "1:34:46"
51
+ }
52
+ ]
53
+ ```
54
+
55
+ The durations are calculated on a per-user basis by default.
56
+ You can change that by supplying either `date` (to group by dates), `weekday`
57
+ (to group by weekdays) or `hour` (to group by day hours) as the `--group-by`
58
+ parameter value.
59
+ For example (assuming that both Jane and Joe spent their time online on Friday,
60
+ June 17, 2016).
61
+
62
+ ```
63
+ > vk-sessions --output-format json --group-by date db.csv
64
+ [
65
+ {
66
+ "date": "2016-06-17",
67
+ "duration": "1:47:17"
68
+ }
69
+ ]
70
+ ```
71
+
72
+ ```
73
+ > vk-sessions --output-format csv --group-by weekday db.csv
74
+ Monday,0:00:00
75
+ Tuesday,0:00:00
76
+ Wednesday,0:00:00
77
+ Thursday,0:00:00
78
+ Friday,1:47:17
79
+ Saturday,0:00:00
80
+ Sunday,0:00:00
81
+ ```
82
+
83
+ ```
84
+ > vk-sessions --group-by hour db.csv
85
+ 0:00:00,0:00:00
86
+ 1:00:00,0:00:00
87
+ 2:00:00,0:00:00
88
+ 3:00:00,0:00:00
89
+ 4:00:00,0:03:56
90
+ 5:00:00,0:14:14
91
+ 6:00:00,0:29:30
92
+ 7:00:00,0:31:20
93
+ 8:00:00,0:12:04
94
+ 9:00:00,0:00:00
95
+ 10:00:00,0:00:00
96
+ 11:00:00,0:23:14
97
+ 12:00:00,0:06:00
98
+ 13:00:00,0:46:19
99
+ 14:00:00,0:00:00
100
+ 15:00:00,0:00:00
101
+ 16:00:00,0:00:00
102
+ 17:00:00,0:00:00
103
+ 18:00:00,0:00:00
104
+ 19:00:00,0:00:00
105
+ 20:00:00,0:00:00
106
+ 21:00:00,0:00:00
107
+ 22:00:00,0:00:00
108
+ 23:00:00,0:00:00
109
+ ```
110
+
111
+ In my opinion, the script's most useful feature is its ability to easily create
112
+ plots that represent this data (like in the examples above).
113
+ To produce a plot, pass `plot` as the `--output-format` parameter value and add
114
+ a file path to write the image to.
115
+
116
+ ```
117
+ > vk-sessions --output-format plot db.csv user.png
118
+ ```
119
+
120
+ ![user.png]
121
+
122
+ ```
123
+ > vk-sessions --output-format plot --group-by date db.csv date.png
124
+ ```
125
+
126
+ ![date.png]
127
+
128
+ ```
129
+ > vk-sessions --output-format plot --group-by weekday db.csv weekday.png
130
+ ```
131
+
132
+ ![weekday.png]
133
+
134
+ ```
135
+ > vk-sessions --output-format plot --group-by hour db.csv hour.png
136
+ ```
137
+
138
+ ![hour.png]
139
+
140
+ You can limit the scope of the database by supplying a time range.
141
+ Only online sessions that overlap with this range shall then be processed.
142
+ Set the range by specifying both or one of the `--from` and `--to` parameters.
143
+ The values must be in the `%Y-%m-%dT%H:%M:%SZ` format (a subset of ISO 8601).
144
+
145
+ All dates and times are in UTC.
146
+
147
+ [matplotlib]: http://matplotlib.org/
148
+ [vk-status]: status.md
149
+
150
+ [user.png]: images/user.png
151
+ [date.png]: images/date.png
152
+ [weekday.png]: images/weekday.png
153
+ [hour.png]: images/hour.png
154
+
155
+ Known issues
156
+ ------------
157
+
158
+ * When people go online using the web version and don't visit other pages over
159
+ time (for example, just listening to music), they appear offline.
160
+ Hence the 0:00:00 durations you might sometimes encounter.
161
+ This might also happen using other clients.
162
+
163
+ See also
164
+ --------
165
+
166
+ * [License]
167
+
168
+ [License]: ../README.md#license
@@ -0,0 +1,40 @@
1
+ vk-status
2
+ =========
3
+
4
+ Track when people go online/offline.
5
+
6
+ Usage
7
+ -----
8
+
9
+ > vk-status -h
10
+ usage: vk-status [-h] [-t SECONDS] [-O] [-l PATH] [-f {csv,log,null}]
11
+ [-o PATH]
12
+ UID [UID ...]
13
+ ...
14
+
15
+ For example (using made up user IDs/"screen names"),
16
+
17
+ > vk-status john.doe jane.smith
18
+ [2016-06-18 01:43:34] John Doe is ONLINE.
19
+ [2016-06-18 01:43:34] John Doe was last seen at 2016-06-18 01:33:58+03:00 using the official iPhone app.
20
+ [2016-06-18 01:43:34] Jane Smith is OFFLINE.
21
+ [2016-06-18 01:43:34] Jane Smith was last seen at 2016-06-18 01:15:47+03:00 using the web version (or an unrecognized app).
22
+ [2016-06-18 01:59:09] Jane Smith went ONLINE.
23
+ [2016-06-18 01:59:09] Jane Smith was last seen at 2016-06-18 01:59:07+03:00 using the official Android app.
24
+ [2016-06-18 02:10:00] John Doe went OFFLINE.
25
+ [2016-06-18 02:10:00] John Doe was last seen at 2016-06-18 01:54:58+03:00 using the official iPhone app.
26
+ ...
27
+
28
+ By default, the script produces a human-readable log.
29
+ Use the `--log` parameter to write the log to a file.
30
+ If you want to record when people go online/offline for further analysis using
31
+ [vk-sessions], specify the path to a database using the `--output` parameter.
32
+
33
+ [vk-sessions]: sessions.md
34
+
35
+ See also
36
+ --------
37
+
38
+ * [License]
39
+
40
+ [License]: ../README.md#license
@@ -0,0 +1,32 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "setuptools-scm"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "vk_scripts"
7
+ description = "Scripts to stalk people on VK"
8
+ license = "MIT"
9
+ dynamic = ["version"]
10
+ authors = [{name = "Egor Tensin", email = "Egor.Tensin@gmail.com"}]
11
+ readme = "README.md"
12
+ requires-python = ">=3.4"
13
+
14
+ dependencies = [
15
+ 'importlib-metadata ~= 4.0 ; python_version < "3.8"',
16
+ "matplotlib",
17
+ ]
18
+
19
+ classifiers = [
20
+ "Development Status :: 4 - Beta",
21
+ ]
22
+
23
+ [project.urls]
24
+ "Homepage" = "https://github.com/egor-tensin/vk-scripts"
25
+ "Bug Tracker" = "https://github.com/egor-tensin/vk-scripts/issues"
26
+
27
+ [project.scripts]
28
+ vk-sessions = "vk.tracking.sessions:main"
29
+ vk-status = "vk.tracking.status:main"
30
+ vk-mutuals = "vk.mutuals:main"
31
+
32
+ [tool.setuptools_scm]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Copyright (c) 2019 Egor Tensin <Egor.Tensin@gmail.com>
4
+ # This file is part of the "VK scripts" project.
5
+ # For details, see https://github.com/egor-tensin/vk-scripts.
6
+ # Distributed under the MIT License.
7
+
8
+ set -o errexit -o nounset -o pipefail
9
+
10
+ script_dir="$( dirname -- "${BASH_SOURCE[0]}" )"
11
+ script_dir="$( cd -- "$script_dir" && pwd )"
12
+ readonly script_dir
13
+
14
+ "$script_dir/mutuals.sh"
15
+
16
+ "$script_dir/sessions.sh"
17
+
18
+ "$script_dir/status_once.sh"
19
+ "$script_dir/status.sh"
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Copyright (c) 2019 Egor Tensin <Egor.Tensin@gmail.com>
4
+ # This file is part of the "VK scripts" project.
5
+ # For details, see https://github.com/egor-tensin/vk-scripts.
6
+ # Distributed under the MIT License.
7
+
8
+ set -o errexit -o nounset -o pipefail
9
+
10
+ script_dir="$( dirname -- "${BASH_SOURCE[0]}" )"
11
+ script_dir="$( cd -- "$script_dir" && pwd )"
12
+ readonly script_dir
13
+
14
+ test_users() {
15
+ "$script_dir/../lib/test.sh" vk.mutuals --format csv "$@"
16
+ "$script_dir/../lib/test.sh" vk.mutuals --format json "$@"
17
+ }
18
+
19
+ main() {
20
+ test_users kreed58 korya_mc
21
+ }
22
+
23
+ main
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Copyright (c) 2019 Egor Tensin <Egor.Tensin@gmail.com>
4
+ # This file is part of the "VK scripts" project.
5
+ # For details, see https://github.com/egor-tensin/vk-scripts.
6
+ # Distributed under the MIT License.
7
+
8
+ set -o errexit -o nounset -o pipefail
9
+
10
+ script_dir="$( dirname -- "${BASH_SOURCE[0]}" )"
11
+ script_dir="$( cd -- "$script_dir" && pwd )"
12
+ readonly script_dir
13
+ script_name="$( basename -- "${BASH_SOURCE[0]}" )"
14
+ readonly script_name
15
+
16
+ readonly db_path="$script_dir/../share/test_db.csv"
17
+
18
+ dump() {
19
+ local msg
20
+ for msg; do
21
+ echo "$script_name: $msg"
22
+ done
23
+ }
24
+
25
+ test_output() {
26
+ local output_path
27
+ output_path="$( mktemp --dry-run )"
28
+
29
+ local rm_aux_files
30
+ rm_aux_files="$( printf -- 'rm -f -- %q' "$output_path" )"
31
+
32
+ trap "$rm_aux_files" RETURN
33
+
34
+ "$script_dir/../lib/test.sh" vk.tracking.sessions "$@" "$db_path" "$output_path"
35
+
36
+ if file --brief --dereference --mime -- "$output_path" | grep --quiet -- 'charset=binary$'; then
37
+ dump 'Output is a binary file, not going to show that'
38
+ return 0
39
+ fi
40
+
41
+ cat "$output_path"
42
+ }
43
+
44
+ group_by() {
45
+ test_output --output-format csv --group-by "$@"
46
+ test_output --output-format json --group-by "$@"
47
+ test_output --output-format plot --group-by "$@"
48
+ }
49
+
50
+ online_sessions() {
51
+ group_by user
52
+ group_by hour
53
+ group_by date
54
+ group_by weekday
55
+ }
56
+
57
+ fix_matplotlib() {
58
+ # Get rid of:
59
+ # tkinter.TclError: no display name and no $DISPLAY environment variable
60
+ mkdir -p -- ~/.config/matplotlib
61
+ echo 'backend: Agg' > ~/.config/matplotlib/matplotlibrc
62
+ }
63
+
64
+ main() {
65
+ fix_matplotlib
66
+ online_sessions
67
+ }
68
+
69
+ main
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Copyright (c) 2019 Egor Tensin <Egor.Tensin@gmail.com>
4
+ # This file is part of the "VK scripts" project.
5
+ # For details, see https://github.com/egor-tensin/vk-scripts.
6
+ # Distributed under the MIT License.
7
+
8
+ set -o errexit -o nounset -o pipefail
9
+
10
+ script_dir="$( dirname -- "${BASH_SOURCE[0]}" )"
11
+ script_dir="$( cd -- "$script_dir" && pwd )"
12
+ readonly script_dir
13
+ script_name="$( basename -- "${BASH_SOURCE[0]}" )"
14
+ readonly script_name
15
+
16
+ dump() {
17
+ local msg
18
+ for msg; do
19
+ echo "$script_name: $msg"
20
+ done
21
+ }
22
+
23
+ test_users() {
24
+ local log_path
25
+ log_path="$( mktemp )"
26
+ local db_path
27
+ db_path="$( mktemp --dry-run )"
28
+
29
+ local rm_aux_files
30
+ rm_aux_files="$( printf -- 'rm -f -- %q %q' "$log_path" "$db_path" )"
31
+ trap "$rm_aux_files" RETURN
32
+
33
+ "$script_dir/../lib/test.sh" vk.tracking.status "$@" --log "$log_path" --format csv --output "$db_path" &
34
+ local pid="$!"
35
+
36
+ sleep 3
37
+ dump "Log file path: $log_path"
38
+ dump "DB file path: $db_path"
39
+ dump "PID: $pid"
40
+
41
+ local timeout=10
42
+ dump "Sleeping for $timeout seconds..."
43
+ sleep "$timeout"
44
+
45
+ dump 'Terminating track_status.py...'
46
+ kill "$pid"
47
+ dump 'Waiting for track_status.py to terminate...'
48
+ wait "$pid" || true
49
+
50
+ dump "Log file:"
51
+ cat "$log_path"
52
+ dump "DB:"
53
+ cat "$db_path"
54
+ }
55
+
56
+ main() {
57
+ test_users egor.tensin
58
+ }
59
+
60
+ main "$@"
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Copyright (c) 2019 Egor Tensin <Egor.Tensin@gmail.com>
4
+ # This file is part of the "VK scripts" project.
5
+ # For details, see https://github.com/egor-tensin/vk-scripts.
6
+ # Distributed under the MIT License.
7
+
8
+ set -o errexit -o nounset -o pipefail
9
+
10
+ script_dir="$( dirname -- "${BASH_SOURCE[0]}" )"
11
+ script_dir="$( cd -- "$script_dir" && pwd )"
12
+ readonly script_dir
13
+
14
+ test_users() {
15
+ "$script_dir/../lib/test.sh" vk.tracking.status --only-once "$@"
16
+ }
17
+
18
+ main() {
19
+ test_users egor.tensin
20
+ }
21
+
22
+ main
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Copyright (c) 2020 Egor Tensin <Egor.Tensin@gmail.com>
4
+ # This file is part of the "VK scripts" project.
5
+ # For details, see https://github.com/egor-tensin/vk-scripts.
6
+ # Distributed under the MIT License.
7
+
8
+ set -o errexit -o nounset -o pipefail
9
+
10
+ script_dir="$( dirname -- "${BASH_SOURCE[0]}" )"
11
+ script_dir="$( cd -- "$script_dir" && pwd )"
12
+ readonly script_dir
13
+
14
+ run_test() {
15
+ local arg
16
+ echo
17
+ echo ======================================================================
18
+ for arg; do
19
+ echo -n "$arg "
20
+ done
21
+ echo
22
+ echo ======================================================================
23
+
24
+ PYTHONPATH="$script_dir/../.." python -m "$@"
25
+ }
26
+
27
+ run_test "$@"
@@ -0,0 +1,45 @@
1
+ 2019-09-09T20:35:46Z,5245998,Egor,Tensin,egor.tensin,True,2019-09-09T20:35:01Z,7
2
+ 2019-09-09T20:35:46Z,80387804,David,Makeev,david.makeev,False,2019-09-09T17:44:23Z,7
3
+ 2019-09-09T20:35:46Z,1172984,Darya,Meluzova,dmeluzova,False,2019-09-09T11:56:03Z,2
4
+ 2019-09-09T20:35:46Z,1052036,Alisa,Bakaeva,alisa.bakaeva,False,2019-09-09T13:30:40Z,4
5
+ 2019-09-09T20:35:46Z,60534,Dina,Semenenko,dina_semenenko,False,2019-09-09T17:20:36Z,1
6
+ 2019-09-09T20:35:46Z,631289,Nikita,Fedorov,nicksarkozy,False,2019-09-09T19:56:54Z,2
7
+ 2019-09-09T20:40:55Z,5245998,Egor,Tensin,egor.tensin,False,2019-09-09T20:35:52Z,7
8
+ 2019-09-09T21:16:33Z,5245998,Egor,Tensin,egor.tensin,True,2019-09-09T21:16:31Z,7
9
+ 2019-09-09T21:23:13Z,5245998,Egor,Tensin,egor.tensin,False,2019-09-09T21:18:10Z,7
10
+ 2019-09-09T21:34:50Z,60534,Dina,Semenenko,dina_semenenko,True,2019-09-09T21:34:49Z,1
11
+ 2019-09-09T21:40:54Z,60534,Dina,Semenenko,dina_semenenko,False,2019-09-09T21:35:52Z,1
12
+ 2019-09-09T22:06:00Z,5245998,Egor,Tensin,egor.tensin,True,2019-09-09T22:05:57Z,7
13
+ 2019-09-09T22:11:29Z,5245998,Egor,Tensin,egor.tensin,False,2019-09-09T22:06:24Z,7
14
+ 2019-09-09T23:28:11Z,5245998,Egor,Tensin,egor.tensin,True,2019-09-09T23:28:06Z,7
15
+ 2019-09-09T23:33:10Z,5245998,Egor,Tensin,egor.tensin,False,2019-09-09T23:28:06Z,7
16
+ 2019-09-09T23:44:42Z,5245998,Egor,Tensin,egor.tensin,True,2019-09-09T23:44:37Z,7
17
+ 2019-09-09T23:49:40Z,5245998,Egor,Tensin,egor.tensin,False,2019-09-09T23:44:37Z,7
18
+ 2019-09-10T00:52:03Z,80387804,David,Makeev,david.makeev,True,2019-09-10T00:52:00Z,4
19
+ 2019-09-10T00:54:50Z,80387804,David,Makeev,david.makeev,False,2019-09-10T00:54:46Z,4
20
+ 2019-09-10T02:50:01Z,80387804,David,Makeev,david.makeev,True,2019-09-10T02:49:58Z,7
21
+ 2019-09-10T03:02:25Z,80387804,David,Makeev,david.makeev,False,2019-09-10T02:57:21Z,7
22
+ 2019-09-10T06:26:08Z,1172984,Darya,Meluzova,dmeluzova,True,2019-09-10T06:26:05Z,2
23
+ 2019-09-10T06:33:23Z,1172984,Darya,Meluzova,dmeluzova,False,2019-09-10T06:28:21Z,2
24
+ 2019-09-10T06:58:01Z,60534,Dina,Semenenko,dina_semenenko,True,2019-09-10T06:58:00Z,1
25
+ 2019-09-10T07:06:47Z,60534,Dina,Semenenko,dina_semenenko,False,2019-09-10T07:01:44Z,1
26
+ 2019-09-10T07:09:24Z,80387804,David,Makeev,david.makeev,True,2019-09-10T07:09:22Z,7
27
+ 2019-09-10T07:15:44Z,80387804,David,Makeev,david.makeev,False,2019-09-10T07:10:42Z,7
28
+ 2019-09-10T07:17:20Z,60534,Dina,Semenenko,dina_semenenko,True,2019-09-10T07:17:15Z,1
29
+ 2019-09-10T07:52:46Z,60534,Dina,Semenenko,dina_semenenko,False,2019-09-10T07:47:45Z,1
30
+ 2019-09-10T07:54:17Z,60534,Dina,Semenenko,dina_semenenko,True,2019-09-10T07:54:13Z,1
31
+ 2019-09-10T08:00:36Z,1172984,Darya,Meluzova,dmeluzova,True,2019-09-10T08:00:35Z,2
32
+ 2019-09-10T08:05:45Z,1172984,Darya,Meluzova,dmeluzova,False,2019-09-10T08:00:43Z,2
33
+ 2019-09-10T08:09:02Z,60534,Dina,Semenenko,dina_semenenko,False,2019-09-10T08:04:00Z,1
34
+ 2019-09-10T08:18:39Z,60534,Dina,Semenenko,dina_semenenko,True,2019-09-10T08:18:36Z,1
35
+ 2019-09-10T08:24:19Z,60534,Dina,Semenenko,dina_semenenko,False,2019-09-10T08:19:17Z,1
36
+ 2019-09-10T08:41:56Z,60534,Dina,Semenenko,dina_semenenko,True,2019-09-10T08:41:53Z,1
37
+ 2019-09-10T08:52:59Z,60534,Dina,Semenenko,dina_semenenko,False,2019-09-10T08:47:57Z,1
38
+ 2019-09-10T09:37:33Z,60534,Dina,Semenenko,dina_semenenko,True,2019-09-10T09:37:30Z,1
39
+ 2019-09-10T09:44:03Z,60534,Dina,Semenenko,dina_semenenko,False,2019-09-10T09:39:02Z,1
40
+ 2019-09-10T10:20:35Z,5245998,Egor,Tensin,egor.tensin,True,2019-09-10T10:20:29Z,7
41
+ 2019-09-10T10:25:34Z,5245998,Egor,Tensin,egor.tensin,False,2019-09-10T10:20:29Z,7
42
+ 2019-09-10T10:27:35Z,631289,Nikita,Fedorov,nicksarkozy,True,2019-09-10T10:27:30Z,7
43
+ 2019-09-10T10:33:14Z,631289,Nikita,Fedorov,nicksarkozy,False,2019-09-10T10:28:10Z,7
44
+ 2019-09-10T10:36:22Z,631289,Nikita,Fedorov,nicksarkozy,True,2019-09-10T10:36:17Z,7
45
+ 2019-09-10T10:41:21Z,631289,Nikita,Fedorov,nicksarkozy,False,2019-09-10T10:36:17Z,7
@@ -64,8 +64,8 @@ ACCESS_TOKEN = '9722cef09722cef09722cef071974b8cbe997229722cef0cbabfd816916af6c7
64
64
 
65
65
 
66
66
  class Version(Enum):
67
- V5_131 = '5.131'
68
- DEFAULT = V5_131
67
+ V5_199 = '5.199'
68
+ DEFAULT = V5_199
69
69
 
70
70
  def __str__(self):
71
71
  return self.value
@@ -12,6 +12,7 @@ import sys
12
12
  from vk.api import API
13
13
  from vk.user import UserField
14
14
  from vk.utils import io
15
+ import vk.version
15
16
 
16
17
 
17
18
  _OUTPUT_USER_FIELDS = UserField.UID, UserField.FIRST_NAME, UserField.LAST_NAME
@@ -84,6 +85,8 @@ def _parse_args(args=None):
84
85
  parser = argparse.ArgumentParser(
85
86
  description='Learn who your ex and her new boyfriend are both friends with.')
86
87
 
88
+ vk.version.add_to_arg_parser(parser)
89
+
87
90
  parser.add_argument('uids', metavar='UID', nargs='+',
88
91
  help='user IDs or "screen names"')
89
92
  parser.add_argument('-f', '--format', dest='out_fmt',
@@ -15,7 +15,7 @@ class Writer(meta.Writer):
15
15
  handler = logging.StreamHandler(fd)
16
16
  handler.setFormatter(logging.Formatter(
17
17
  fmt='[%(asctime)s] %(message)s',
18
- datefmt='%Y-%m-%d %H:%M:%S'))
18
+ datefmt='%Y-%m-%d %H:%M:%S%z'))
19
19
  self._logger.addHandler(handler)
20
20
 
21
21
  self._reset_last_notification()
@@ -15,6 +15,7 @@ from vk.tracking.db import Format as DatabaseFormat
15
15
  from vk.user import UserField
16
16
  from vk.utils.bar_chart import BarChartBuilder
17
17
  from vk.utils import io
18
+ import vk.version
18
19
 
19
20
 
20
21
  class Weekday(Enum):
@@ -436,6 +437,8 @@ def _parse_args(args=None):
436
437
  parser = argparse.ArgumentParser(
437
438
  description='View/visualize the amount of time people spend online.')
438
439
 
440
+ vk.version.add_to_arg_parser(parser)
441
+
439
442
  parser.add_argument('db_path', metavar='input', nargs='?',
440
443
  help='database file path (standard input by default)')
441
444
  parser.add_argument('out_path', metavar='output', nargs='?',
@@ -12,8 +12,9 @@ import sys
12
12
 
13
13
  from vk.api import API
14
14
  import vk.error
15
- from vk.user import UserField
16
15
  from vk.tracking.db import Format as DatabaseFormat
16
+ from vk.user import UserField
17
+ import vk.version
17
18
 
18
19
 
19
20
  class StatusTracker:
@@ -171,6 +172,8 @@ def _parse_args(args=None):
171
172
  parser = argparse.ArgumentParser(
172
173
  description='Track when people go online/offline.')
173
174
 
175
+ vk.version.add_to_arg_parser(parser)
176
+
174
177
  parser.add_argument('uids', metavar='UID', nargs='+',
175
178
  help='user IDs or "screen names"')
176
179
  parser.add_argument('-t', '--timeout', metavar='SECONDS',
@@ -0,0 +1,15 @@
1
+ try:
2
+ import importlib.metadata as metadata
3
+ except ImportError:
4
+ import importlib_metadata as metadata
5
+
6
+
7
+ try:
8
+ __version__ = metadata.version('vk_scripts')
9
+ except Exception:
10
+ __version__ = 'unknown'
11
+
12
+
13
+ def add_to_arg_parser(parser):
14
+ parser.add_argument('--version', '-V', action='version',
15
+ version=f'%(prog)s {__version__}')
@@ -1,18 +1,18 @@
1
- Metadata-Version: 2.1
2
- Name: vk-scripts
3
- Version: 1.0.2
1
+ Metadata-Version: 2.4
2
+ Name: vk_scripts
3
+ Version: 1.0.4
4
4
  Summary: Scripts to stalk people on VK
5
- Home-page: https://github.com/egor-tensin/vk-scripts
6
- Author: Egor Tensin
7
- Author-email: Egor.Tensin@gmail.com
8
- License: MIT
5
+ Author-email: Egor Tensin <Egor.Tensin@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/egor-tensin/vk-scripts
9
8
  Project-URL: Bug Tracker, https://github.com/egor-tensin/vk-scripts/issues
10
- Platform: UNKNOWN
11
9
  Classifier: Development Status :: 4 - Beta
12
- Classifier: License :: OSI Approved :: MIT License
13
10
  Requires-Python: >=3.4
14
11
  Description-Content-Type: text/markdown
15
12
  License-File: LICENSE.txt
13
+ Requires-Dist: importlib-metadata~=4.0; python_version < "3.8"
14
+ Requires-Dist: matplotlib
15
+ Dynamic: license-file
16
16
 
17
17
  VK scripts
18
18
  ==========
@@ -55,6 +55,14 @@ Requires [Pylint].
55
55
 
56
56
  [Pylint]: https://www.pylint.org/
57
57
 
58
+ ### Releases
59
+
60
+ Make a git tag:
61
+
62
+ git tag "v$( python -m setuptools_scm --strip-dev )"
63
+
64
+ You can then review that the tag is fine and push w/ `git push --tags`.
65
+
58
66
  License
59
67
  -------
60
68
 
@@ -62,5 +70,3 @@ Distributed under the MIT License.
62
70
  See [LICENSE.txt] for details.
63
71
 
64
72
  [LICENSE.txt]: LICENSE.txt
65
-
66
-
@@ -1,8 +1,25 @@
1
+ .gitattributes
2
+ .gitignore
3
+ .pylintrc
1
4
  LICENSE.txt
2
5
  README.md
3
6
  pyproject.toml
4
- setup.cfg
5
- setup.py
7
+ .github/dependabot.yml
8
+ .github/workflows/ci.yml
9
+ docs/mutuals.md
10
+ docs/sessions.md
11
+ docs/status.md
12
+ docs/images/date.png
13
+ docs/images/hour.png
14
+ docs/images/user.png
15
+ docs/images/weekday.png
16
+ test/bin/main.sh
17
+ test/bin/mutuals.sh
18
+ test/bin/sessions.sh
19
+ test/bin/status.sh
20
+ test/bin/status_once.sh
21
+ test/lib/test.sh
22
+ test/share/test_db.csv
6
23
  vk/__init__.py
7
24
  vk/api.py
8
25
  vk/error.py
@@ -10,6 +27,7 @@ vk/last_seen.py
10
27
  vk/mutuals.py
11
28
  vk/platform.py
12
29
  vk/user.py
30
+ vk/version.py
13
31
  vk/tracking/__init__.py
14
32
  vk/tracking/sessions.py
15
33
  vk/tracking/status.py
@@ -2,4 +2,3 @@
2
2
  vk-mutuals = vk.mutuals:main
3
3
  vk-sessions = vk.tracking.sessions:main
4
4
  vk-status = vk.tracking.status:main
5
-
@@ -0,0 +1,4 @@
1
+ matplotlib
2
+
3
+ [:python_version < "3.8"]
4
+ importlib-metadata~=4.0
@@ -1,3 +0,0 @@
1
- [build-system]
2
- requires = ["setuptools", "wheel"]
3
- build-backend = "setuptools.build_meta"
@@ -1,32 +0,0 @@
1
- [metadata]
2
- name = vk_scripts
3
- version = 1.0.2
4
- author = Egor Tensin
5
- author_email = Egor.Tensin@gmail.com
6
- description = Scripts to stalk people on VK
7
- long_description = file: README.md
8
- long_description_content_type = text/markdown
9
- license = MIT
10
- url = https://github.com/egor-tensin/vk-scripts
11
- project_urls =
12
- Bug Tracker = https://github.com/egor-tensin/vk-scripts/issues
13
- classifiers =
14
- Development Status :: 4 - Beta
15
- License :: OSI Approved :: MIT License
16
-
17
- [options]
18
- packages = find:
19
- python_requires = >=3.4
20
- install_requires =
21
- matplotlib
22
-
23
- [options.entry_points]
24
- console_scripts =
25
- vk-sessions = vk.tracking.sessions:main
26
- vk-status = vk.tracking.status:main
27
- vk-mutuals = vk.mutuals:main
28
-
29
- [egg_info]
30
- tag_build =
31
- tag_date = 0
32
-
vk_scripts-1.0.2/setup.py DELETED
@@ -1,2 +0,0 @@
1
- import setuptools
2
- setuptools.setup()
@@ -1 +0,0 @@
1
- matplotlib
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes